| /* |
| * Copyright (C) 2013 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 android.print; |
| |
| import android.os.Parcel; |
| import android.os.Parcelable; |
| import android.print.PrintAttributes.Margins; |
| import android.print.PrintAttributes.MediaSize; |
| import android.print.PrintAttributes.Resolution; |
| import android.print.PrintAttributes.Tray; |
| import android.text.TextUtils; |
| import android.util.SparseIntArray; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| /** |
| * This class represents the description of a printer. A description |
| * contains the printer id, human readable name, status, and available |
| * options for various printer capabilities, such as media size, etc. |
| */ |
| public final class PrinterInfo implements Parcelable { |
| /** |
| * Undefined default value. |
| * |
| * @hide |
| */ |
| public static final int DEFAULT_UNDEFINED = -1; |
| |
| private static final int MIN_COPIES = 1; |
| |
| private static final int PROPERTY_MEDIA_SIZE = 0; |
| private static final int PROPERTY_RESOLUTION = 1; |
| private static final int PROPERTY_INPUT_TRAY = 2; |
| private static final int PROPERTY_OUTPUT_TRAY = 3; |
| private static final int PROPERTY_DUPLEX_MODE = 4; |
| private static final int PROPERTY_COLOR_MODE = 5; |
| private static final int PROPERTY_FITTING_MODE = 6; |
| private static final int PROPERTY_ORIENTATION = 7; |
| |
| /** Printer status: the printer is ready to print. */ |
| public static final int STATUS_READY = 1; |
| |
| // TODO: Add printer status constants. |
| |
| private PrinterId mId; |
| private CharSequence mLabel; |
| private int mStatus; |
| |
| private Margins mMinMargins; |
| private final List<MediaSize> mMediaSizes = new ArrayList<MediaSize>(); // required |
| private final List<Resolution> mResolutions = new ArrayList<Resolution>(); // required |
| private List<Tray> mInputTrays; |
| private List<Tray> mOutputTrays; |
| |
| private int mDuplexModes; |
| private int mColorModes; |
| private int mFittingModes; |
| private int mOrientations; |
| |
| private final SparseIntArray mDefaults = new SparseIntArray(); |
| private Margins mDefaultMargins; |
| |
| private PrinterInfo() { |
| mDefaults.put(PROPERTY_MEDIA_SIZE, DEFAULT_UNDEFINED); |
| mDefaults.put(PROPERTY_RESOLUTION, DEFAULT_UNDEFINED); |
| mDefaults.put(PROPERTY_INPUT_TRAY, DEFAULT_UNDEFINED); |
| mDefaults.put(PROPERTY_OUTPUT_TRAY, DEFAULT_UNDEFINED); |
| mDefaults.put(PROPERTY_DUPLEX_MODE, DEFAULT_UNDEFINED); |
| mDefaults.put(PROPERTY_COLOR_MODE, DEFAULT_UNDEFINED); |
| mDefaults.put(PROPERTY_FITTING_MODE, DEFAULT_UNDEFINED); |
| mDefaults.put(PROPERTY_ORIENTATION, DEFAULT_UNDEFINED); |
| } |
| |
| private PrinterInfo(PrinterInfo prototype) { |
| mId = prototype.mId; |
| mLabel = prototype.mLabel; |
| mStatus = prototype.mStatus; |
| |
| mMinMargins = prototype.mMinMargins; |
| mMediaSizes.addAll(prototype.mMediaSizes); |
| mResolutions.addAll(prototype.mResolutions); |
| mInputTrays = (prototype.mInputTrays != null) |
| ? new ArrayList<Tray>(prototype.mInputTrays) : null; |
| mOutputTrays = (prototype.mOutputTrays != null) |
| ? new ArrayList<Tray>(prototype.mOutputTrays) : null; |
| |
| mDuplexModes = prototype.mDuplexModes; |
| mColorModes = prototype.mColorModes; |
| mFittingModes = prototype.mFittingModes; |
| mOrientations = prototype.mOrientations; |
| |
| final int defaultCount = prototype.mDefaults.size(); |
| for (int i = 0; i < defaultCount; i++) { |
| mDefaults.put(prototype.mDefaults.keyAt(i), prototype.mDefaults.valueAt(i)); |
| } |
| mDefaultMargins = prototype.mDefaultMargins; |
| } |
| |
| /** |
| * Get the globally unique printer id. |
| * |
| * @return The printer id. |
| */ |
| public PrinterId getId() { |
| return mId; |
| } |
| |
| /** |
| * Gets the human readable printer label. |
| * |
| * @return The human readable label. |
| */ |
| public CharSequence getLabel() { |
| return mLabel; |
| } |
| |
| /** |
| * Gets the status of the printer. |
| * |
| * @return The status. |
| */ |
| public int getStatus() { |
| return mStatus; |
| } |
| |
| /** |
| * Gets the supported media sizes. |
| * |
| * @return The supported media sizes. |
| */ |
| public List<MediaSize> getMediaSizes() { |
| return mMediaSizes; |
| } |
| |
| /** |
| * Gets the supported resolutions. |
| * |
| * @return The supported resolutions. |
| */ |
| public List<Resolution> getResolutions() { |
| return mResolutions; |
| } |
| |
| /** |
| * Gets the minimal supported margins. |
| * |
| * @return The minimal margins. |
| */ |
| public Margins getMinMargins() { |
| return mMinMargins; |
| } |
| |
| /** |
| * Gets the available input trays. |
| * |
| * @return The input trays. |
| */ |
| public List<Tray> getInputTrays() { |
| return mInputTrays; |
| } |
| |
| /** |
| * Gets the available output trays. |
| * |
| * @return The output trays. |
| */ |
| public List<Tray> getOutputTrays() { |
| return mOutputTrays; |
| } |
| |
| /** |
| * Gets the supported duplex modes. |
| * |
| * @return The duplex modes. |
| * |
| * @see PrintAttributes#DUPLEX_MODE_NONE |
| * @see PrintAttributes#DUPLEX_MODE_LONG_EDGE |
| * @see PrintAttributes#DUPLEX_MODE_SHORT_EDGE |
| */ |
| public int getDuplexModes() { |
| return mDuplexModes; |
| } |
| |
| /** |
| * Gets the supported color modes. |
| * |
| * @return The color modes. |
| * |
| * @see PrintAttributes#COLOR_MODE_COLOR |
| * @see PrintAttributes#COLOR_MODE_MONOCHROME |
| */ |
| public int getColorModes() { |
| return mColorModes; |
| } |
| |
| /** |
| * Gets the supported fitting modes. |
| * |
| * @return The fitting modes. |
| * |
| * @see PrintAttributes#FITTING_MODE_NONE |
| * @see PrintAttributes#FITTING_MODE_FIT_TO_PAGE |
| */ |
| public int getFittingModes() { |
| return mFittingModes; |
| } |
| |
| /** |
| * Gets the supported orientations. |
| * |
| * @return The orientations. |
| * |
| * @see PrintAttributes#ORIENTATION_PORTRAIT |
| * @see PrintAttributes#ORIENTATION_LANDSCAPE |
| */ |
| public int getOrientations() { |
| return mOrientations; |
| } |
| |
| /** |
| * Gets the default print attributes. |
| * |
| * @param outAttributes The attributes to populated. |
| */ |
| public void getDefaults(PrintAttributes outAttributes) { |
| outAttributes.clear(); |
| |
| // TODO: Do we want a printer to specify default copies? |
| outAttributes.setCopies(MIN_COPIES); |
| |
| outAttributes.setMargins(mDefaultMargins); |
| |
| final int mediaSizeIndex = mDefaults.get(PROPERTY_MEDIA_SIZE); |
| if (mediaSizeIndex >= 0) { |
| outAttributes.setMediaSize(mMediaSizes.get(mediaSizeIndex)); |
| } |
| |
| final int resolutionIndex = mDefaults.get(PROPERTY_RESOLUTION); |
| if (resolutionIndex >= 0) { |
| outAttributes.setResolution(mResolutions.get(resolutionIndex)); |
| } |
| |
| final int inputTrayIndex = mDefaults.get(PROPERTY_INPUT_TRAY); |
| if (inputTrayIndex >= 0) { |
| outAttributes.setInputTray(mInputTrays.get(inputTrayIndex)); |
| } |
| |
| final int outputTrayIndex = mDefaults.get(PROPERTY_OUTPUT_TRAY); |
| if (outputTrayIndex >= 0) { |
| outAttributes.setOutputTray(mOutputTrays.get(outputTrayIndex)); |
| } |
| |
| final int duplexMode = mDefaults.get(PROPERTY_DUPLEX_MODE); |
| if (duplexMode > 0) { |
| outAttributes.setDuplexMode(duplexMode); |
| } |
| |
| final int colorMode = mDefaults.get(PROPERTY_COLOR_MODE); |
| if (colorMode > 0) { |
| outAttributes.setColorMode(mColorModes & colorMode); |
| } |
| |
| final int fittingMode = mDefaults.get(PROPERTY_FITTING_MODE); |
| if (fittingMode > 0) { |
| outAttributes.setFittingMode(fittingMode); |
| } |
| |
| final int orientation = mDefaults.get(PROPERTY_ORIENTATION); |
| if (orientation > 0) { |
| outAttributes.setOrientation(orientation); |
| } |
| } |
| |
| private PrinterInfo(Parcel parcel) { |
| mId = parcel.readParcelable(null); |
| mLabel = parcel.readCharSequence(); |
| mStatus = parcel.readInt(); |
| |
| mMinMargins = readMargins(parcel); |
| readMediaSizes(parcel); |
| readResolutions(parcel); |
| mInputTrays = readInputTrays(parcel); |
| mOutputTrays = readOutputTrays(parcel); |
| |
| mColorModes = parcel.readInt(); |
| mDuplexModes = parcel.readInt(); |
| mFittingModes = parcel.readInt(); |
| mOrientations = parcel.readInt(); |
| |
| readDefaults(parcel); |
| mDefaultMargins = readMargins(parcel); |
| } |
| |
| @Override |
| public int describeContents() { |
| return 0; |
| } |
| |
| @Override |
| public void writeToParcel(Parcel parcel, int flags) { |
| parcel.writeParcelable(mId, flags); |
| parcel.writeCharSequence(mLabel); |
| parcel.writeInt(mStatus); |
| |
| writeMargins(mMinMargins, parcel); |
| writeMediaSizes(parcel); |
| writeResolutions(parcel); |
| writeInputTrays(parcel); |
| writeOutputTrays(parcel); |
| |
| parcel.writeInt(mColorModes); |
| parcel.writeInt(mDuplexModes); |
| parcel.writeInt(mFittingModes); |
| parcel.writeInt(mOrientations); |
| |
| writeDefaults(parcel); |
| writeMargins(mDefaultMargins, parcel); |
| } |
| |
| @Override |
| public String toString() { |
| StringBuilder builder = new StringBuilder(); |
| builder.append("PrinterInfo{"); |
| builder.append(mId).append(", \""); |
| builder.append(mLabel); |
| builder.append("\"}"); |
| return builder.toString(); |
| } |
| |
| private void writeMediaSizes(Parcel parcel) { |
| if (mMediaSizes == null) { |
| parcel.writeInt(0); |
| return; |
| } |
| final int mediaSizeCount = mMediaSizes.size(); |
| parcel.writeInt(mediaSizeCount); |
| for (int i = 0; i < mediaSizeCount; i++) { |
| mMediaSizes.get(i).writeToParcel(parcel); |
| } |
| } |
| |
| private void readMediaSizes(Parcel parcel) { |
| final int mediaSizeCount = parcel.readInt(); |
| for (int i = 0; i < mediaSizeCount; i++) { |
| mMediaSizes.add(MediaSize.createFromParcel(parcel)); |
| } |
| } |
| |
| private void writeResolutions(Parcel parcel) { |
| final int resolutionCount = mResolutions.size(); |
| parcel.writeInt(resolutionCount); |
| for (int i = 0; i < resolutionCount; i++) { |
| mResolutions.get(i).writeToParcel(parcel); |
| } |
| } |
| |
| private void readResolutions(Parcel parcel) { |
| final int resolutionCount = parcel.readInt(); |
| for (int i = 0; i < resolutionCount; i++) { |
| mResolutions.add(Resolution.createFromParcel(parcel)); |
| } |
| } |
| |
| private void writeMargins(Margins margins, Parcel parcel) { |
| if (margins == null) { |
| parcel.writeInt(0); |
| } else { |
| parcel.writeInt(1); |
| margins.writeToParcel(parcel); |
| } |
| } |
| |
| private Margins readMargins(Parcel parcel) { |
| return (parcel.readInt() == 1) ? Margins.createFromParcel(parcel) : null; |
| } |
| |
| private void writeInputTrays(Parcel parcel) { |
| if (mInputTrays == null) { |
| parcel.writeInt(0); |
| return; |
| } |
| final int inputTrayCount = mInputTrays.size(); |
| parcel.writeInt(inputTrayCount); |
| for (int i = 0; i < inputTrayCount; i++) { |
| mInputTrays.get(i).writeToParcel(parcel); |
| } |
| } |
| |
| private List<Tray> readInputTrays(Parcel parcel) { |
| final int inputTrayCount = parcel.readInt(); |
| if (inputTrayCount <= 0) { |
| return null; |
| } |
| List<Tray> inputTrays = new ArrayList<Tray>(inputTrayCount); |
| for (int i = 0; i < inputTrayCount; i++) { |
| inputTrays.add(Tray.createFromParcel(parcel)); |
| } |
| return inputTrays; |
| } |
| |
| private void writeOutputTrays(Parcel parcel) { |
| if (mOutputTrays == null) { |
| parcel.writeInt(0); |
| return; |
| } |
| final int outputTrayCount = mOutputTrays.size(); |
| parcel.writeInt(outputTrayCount); |
| for (int i = 0; i < outputTrayCount; i++) { |
| mOutputTrays.get(i).writeToParcel(parcel); |
| } |
| } |
| |
| private List<Tray> readOutputTrays(Parcel parcel) { |
| final int outputTrayCount = parcel.readInt(); |
| if (outputTrayCount <= 0) { |
| return null; |
| } |
| List<Tray> outputTrays = new ArrayList<Tray>(outputTrayCount); |
| for (int i = 0; i < outputTrayCount; i++) { |
| outputTrays.add(Tray.createFromParcel(parcel)); |
| } |
| return outputTrays; |
| } |
| |
| private void readDefaults(Parcel parcel) { |
| final int defaultCount = parcel.readInt(); |
| for (int i = 0; i < defaultCount; i++) { |
| mDefaults.append(mDefaults.size(), parcel.readInt()); |
| } |
| } |
| |
| private void writeDefaults(Parcel parcel) { |
| final int defaultCount = mDefaults.size(); |
| parcel.writeInt(defaultCount); |
| for (int i = 0; i < defaultCount; i++) { |
| parcel.writeInt(mDefaults.valueAt(i)); |
| } |
| } |
| |
| /** |
| * Builder for creating of a {@link PrinterInfo}. This class is responsible |
| * to enforce that all required attributes have at least one default value. |
| * In other words, this class creates only well-formed {@link PrinterInfo}s. |
| * <p> |
| * Look at the individual methods for a reference whether a property is |
| * required or if it is optional. |
| * </p> |
| */ |
| public static final class Builder { |
| private final PrinterInfo mPrototype; |
| |
| /** |
| * Creates a new instance. |
| * |
| * @param printerId The printer id. |
| * @param label The human readable printer label. |
| * |
| * @throws IllegalArgumentException IF the printer id is null. |
| * @throws IllegalArgumentException IF the label is empty. |
| */ |
| public Builder(PrinterId printerId, CharSequence label) { |
| if (printerId == null) { |
| throw new IllegalArgumentException("printerId cannot be null."); |
| } |
| if (TextUtils.isEmpty(label)) { |
| throw new IllegalArgumentException("label cannot be empty."); |
| } |
| mPrototype = new PrinterInfo(); |
| mPrototype.mLabel = label; |
| mPrototype.mId = printerId; |
| } |
| |
| /** |
| * Sets the printer status. |
| * <p> |
| * <strong>Required:</strong> Yes |
| * </p> |
| * |
| * @param status The status. |
| * @return This builder. |
| */ |
| public Builder setStatus(int status) { |
| mPrototype.mStatus = status; |
| return this; |
| } |
| |
| /** |
| * Adds a supported media size. |
| * <p> |
| * <strong>Required:</strong> Yes |
| * </p> |
| * |
| * @param mediaSize A media size. |
| * @param isDefault Whether this is the default. |
| * @return This builder. |
| * @throws IllegalArgumentException If set as default and there |
| * is already a default. |
| * |
| * @see PrintAttributes.MediaSize |
| */ |
| public Builder addMediaSize(MediaSize mediaSize, boolean isDefault) { |
| final int insertionIndex = mPrototype.mMediaSizes.size(); |
| mPrototype.mMediaSizes.add(mediaSize); |
| if (isDefault) { |
| throwIfDefaultAlreadySpecified(PROPERTY_MEDIA_SIZE); |
| mPrototype.mDefaults.put(PROPERTY_MEDIA_SIZE, insertionIndex); |
| } |
| return this; |
| } |
| |
| /** |
| * Adds a supported resolution. |
| * <p> |
| * <strong>Required:</strong> Yes |
| * </p> |
| * |
| * @param resolution A resolution. |
| * @param isDefault Whether this is the default. |
| * @return This builder. |
| * |
| * @throws IllegalArgumentException If set as default and there |
| * is already a default. |
| * |
| * @see PrintAttributes.Resolution |
| */ |
| public Builder addResolution(Resolution resolution, boolean isDefault) { |
| final int insertionIndex = mPrototype.mResolutions.size(); |
| mPrototype.mResolutions.add(resolution); |
| if (isDefault) { |
| throwIfDefaultAlreadySpecified(PROPERTY_RESOLUTION); |
| mPrototype.mDefaults.put(PROPERTY_RESOLUTION, insertionIndex); |
| } |
| return this; |
| } |
| |
| /** |
| * Sets the minimal margins. |
| * <p> |
| * <strong>Required:</strong> No |
| * </p> |
| * |
| * @param margins The margins. |
| * @param defaultMargins The default margins. |
| * @return This builder. |
| * |
| * @see PrintAttributes.Margins |
| */ |
| public Builder setMinMargins(Margins margins, Margins defaultMargins) { |
| if (margins.getLeftMils() > defaultMargins.getLeftMils() |
| || margins.getTopMils() > defaultMargins.getTopMils() |
| || margins.getRightMils() < defaultMargins.getRightMils() |
| || margins.getBottomMils() < defaultMargins.getBottomMils()) { |
| throw new IllegalArgumentException("Default margins" |
| + " cannot be outside of the min margins."); |
| } |
| mPrototype.mMinMargins = margins; |
| mPrototype.mDefaultMargins = defaultMargins; |
| return this; |
| } |
| |
| /** |
| * Adds an input tray. |
| * <p> |
| * <strong>Required:</strong> No |
| * </p> |
| * |
| * @param inputTray A tray. |
| * @param isDefault Whether this is the default. |
| * @return This builder. |
| * |
| * @throws IllegalArgumentException If set as default and there |
| * is already a default. |
| * |
| * @see PrintAttributes.Tray |
| */ |
| public Builder addInputTray(Tray inputTray, boolean isDefault) { |
| if (mPrototype.mInputTrays == null) { |
| mPrototype.mInputTrays = new ArrayList<Tray>(); |
| } |
| final int insertionIndex = mPrototype.mInputTrays.size(); |
| mPrototype.mInputTrays.add(inputTray); |
| if (isDefault) { |
| throwIfDefaultAlreadySpecified(PROPERTY_INPUT_TRAY); |
| mPrototype.mDefaults.put(PROPERTY_INPUT_TRAY, insertionIndex); |
| } |
| return this; |
| } |
| |
| /** |
| * Adds an output tray. |
| * <p> |
| * <strong>Required:</strong> No |
| * </p> |
| * |
| * @param outputTray A tray. |
| * @param isDefault Whether this is the default. |
| * @return This builder. |
| * |
| * @throws IllegalArgumentException If set as default and there |
| * is already a default. |
| * |
| * @see PrintAttributes.Tray |
| */ |
| public Builder addOutputTray(Tray outputTray, boolean isDefault) { |
| if (mPrototype.mOutputTrays == null) { |
| mPrototype.mOutputTrays = new ArrayList<Tray>(); |
| } |
| final int insertionIndex = mPrototype.mOutputTrays.size(); |
| mPrototype.mOutputTrays.add(outputTray); |
| if (isDefault) { |
| throwIfDefaultAlreadySpecified(PROPERTY_OUTPUT_TRAY); |
| mPrototype.mDefaults.put(PROPERTY_OUTPUT_TRAY, insertionIndex); |
| } |
| return this; |
| } |
| |
| /** |
| * Sets the color modes. |
| * <p> |
| * <strong>Required:</strong> Yes |
| * </p> |
| * |
| * @param colorModes The color mode bit mask. |
| * @param defaultColorMode The default color mode. |
| * @return This builder. |
| * |
| * @throws IllegalArgumentException If color modes contains an invalid |
| * mode bit or if the default color mode is invalid. |
| * |
| * @see PrintAttributes#COLOR_MODE_COLOR |
| * @see PrintAttributes#COLOR_MODE_MONOCHROME |
| */ |
| public Builder setColorModes(int colorModes, int defaultColorMode) { |
| int currentModes = colorModes; |
| while (currentModes > 0) { |
| final int currentMode = (1 << Integer.numberOfTrailingZeros(currentModes)); |
| currentModes &= ~currentMode; |
| PrintAttributes.enforceValidColorMode(currentMode); |
| } |
| if ((colorModes & defaultColorMode) == 0) { |
| throw new IllegalArgumentException("Default color mode not in color modes."); |
| } |
| PrintAttributes.enforceValidColorMode(colorModes); |
| mPrototype.mColorModes = colorModes; |
| mPrototype.mDefaults.put(PROPERTY_COLOR_MODE, defaultColorMode); |
| return this; |
| } |
| |
| /** |
| * Set the duplex modes. |
| * <p> |
| * <strong>Required:</strong> No |
| * </p> |
| * |
| * @param duplexModes The duplex mode bit mask. |
| * @param defaultDuplexMode The default duplex mode. |
| * @return This builder. |
| * |
| * @throws IllegalArgumentException If duplex modes contains an invalid |
| * mode bit or if the default duplex mode is invalid. |
| * |
| * @see PrintAttributes#DUPLEX_MODE_NONE |
| * @see PrintAttributes#DUPLEX_MODE_LONG_EDGE |
| * @see PrintAttributes#DUPLEX_MODE_SHORT_EDGE |
| */ |
| public Builder setDuplexModes(int duplexModes, int defaultDuplexMode) { |
| int currentModes = duplexModes; |
| while (currentModes > 0) { |
| final int currentMode = (1 << Integer.numberOfTrailingZeros(currentModes)); |
| currentModes &= ~currentMode; |
| PrintAttributes.enforceValidDuplexMode(currentMode); |
| } |
| if ((duplexModes & defaultDuplexMode) == 0) { |
| throw new IllegalArgumentException("Default duplex mode not in duplex modes."); |
| } |
| PrintAttributes.enforceValidDuplexMode(defaultDuplexMode); |
| mPrototype.mDuplexModes = duplexModes; |
| mPrototype.mDefaults.put(PROPERTY_DUPLEX_MODE, defaultDuplexMode); |
| return this; |
| } |
| |
| /** |
| * Sets the fitting modes. |
| * <p> |
| * <strong>Required:</strong> No |
| * </p> |
| * |
| * @param fittingModes The fitting mode bit mask. |
| * @param defaultFittingMode The default fitting mode. |
| * @return This builder. |
| * |
| * @throws IllegalArgumentException If fitting modes contains an invalid |
| * mode bit or if the default fitting mode is invalid. |
| * |
| * @see PrintAttributes#FITTING_MODE_NONE |
| * @see PrintAttributes#FITTING_MODE_FIT_TO_PAGE |
| */ |
| public Builder setFittingModes(int fittingModes, int defaultFittingMode) { |
| int currentModes = fittingModes; |
| while (currentModes > 0) { |
| final int currentMode = (1 << Integer.numberOfTrailingZeros(currentModes)); |
| currentModes &= ~currentMode; |
| PrintAttributes.enfoceValidFittingMode(currentMode); |
| } |
| if ((fittingModes & defaultFittingMode) == 0) { |
| throw new IllegalArgumentException("Default fitting mode not in fiting modes."); |
| } |
| PrintAttributes.enfoceValidFittingMode(defaultFittingMode); |
| mPrototype.mFittingModes = fittingModes; |
| mPrototype.mDefaults.put(PROPERTY_FITTING_MODE, defaultFittingMode); |
| return this; |
| } |
| |
| /** |
| * Sets the orientations. |
| * <p> |
| * <strong>Required:</strong> Yes |
| * </p> |
| * |
| * @param orientations The orientation bit mask. |
| * @param defaultOrientation The default orientation. |
| * @return This builder. |
| * |
| * @throws IllegalArgumentException If orientations contains an invalid |
| * mode bit or if the default orientation is invalid. |
| * |
| * @see PrintAttributes#ORIENTATION_PORTRAIT |
| * @see PrintAttributes#ORIENTATION_LANDSCAPE |
| */ |
| public Builder setOrientations(int orientations, int defaultOrientation) { |
| int currentOrientaions = orientations; |
| while (currentOrientaions > 0) { |
| final int currentOrnt = (1 << Integer.numberOfTrailingZeros(currentOrientaions)); |
| currentOrientaions &= ~currentOrnt; |
| PrintAttributes.enforceValidOrientation(currentOrnt); |
| } |
| if ((orientations & defaultOrientation) == 0) { |
| throw new IllegalArgumentException("Default orientation not in orientations."); |
| } |
| PrintAttributes.enforceValidOrientation(defaultOrientation); |
| mPrototype.mOrientations = orientations; |
| mPrototype.mDefaults.put(PROPERTY_ORIENTATION, defaultOrientation); |
| return this; |
| } |
| |
| /** |
| * Crates a new {@link PrinterInfo} enforcing that all required properties |
| * have need specified. See individual methods in this class for reference |
| * about required attributes. |
| * |
| * @return A new {@link PrinterInfo}. |
| * |
| * @throws IllegalStateException If a required attribute was not specified. |
| */ |
| public PrinterInfo create() { |
| if (mPrototype.mMediaSizes == null || mPrototype.mMediaSizes.isEmpty()) { |
| throw new IllegalStateException("No media size specified."); |
| } |
| if (mPrototype.mDefaults.valueAt(PROPERTY_MEDIA_SIZE) == DEFAULT_UNDEFINED) { |
| throw new IllegalStateException("No default media size specified."); |
| } |
| if (mPrototype.mResolutions == null || mPrototype.mResolutions.isEmpty()) { |
| throw new IllegalStateException("No resolution specified."); |
| } |
| if (mPrototype.mDefaults.valueAt(PROPERTY_RESOLUTION) == DEFAULT_UNDEFINED) { |
| throw new IllegalStateException("No default resolution specified."); |
| } |
| if (mPrototype.mColorModes == 0) { |
| throw new IllegalStateException("No color mode specified."); |
| } |
| if (mPrototype.mDefaults.valueAt(PROPERTY_COLOR_MODE) == DEFAULT_UNDEFINED) { |
| throw new IllegalStateException("No default color mode specified."); |
| } |
| if (mPrototype.mOrientations == 0) { |
| throw new IllegalStateException("No oprientation specified."); |
| } |
| if (mPrototype.mDefaults.valueAt(PROPERTY_ORIENTATION) == DEFAULT_UNDEFINED) { |
| throw new IllegalStateException("No default orientation specified."); |
| } |
| if (mPrototype.mMinMargins == null) { |
| mPrototype.mMinMargins = new Margins(0, 0, 0, 0); |
| } |
| if (mPrototype.mDefaultMargins == null) { |
| mPrototype.mDefaultMargins = mPrototype.mMinMargins; |
| } |
| return new PrinterInfo(mPrototype); |
| } |
| |
| private void throwIfDefaultAlreadySpecified(int propertyIndex) { |
| if (mPrototype.mDefaults.get(propertyIndex) != DEFAULT_UNDEFINED) { |
| throw new IllegalArgumentException("Default already specified."); |
| } |
| } |
| } |
| |
| public static final Parcelable.Creator<PrinterInfo> CREATOR = |
| new Parcelable.Creator<PrinterInfo>() { |
| @Override |
| public PrinterInfo createFromParcel(Parcel parcel) { |
| return new PrinterInfo(parcel); |
| } |
| |
| @Override |
| public PrinterInfo[] newArray(int size) { |
| return new PrinterInfo[size]; |
| } |
| }; |
| } |