PrintAttributes.java revision 17b7f6e6d4ec9f5e9597bfd283f1c017b6c66275
1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.print;
18
19import android.content.pm.PackageManager;
20import android.content.pm.PackageManager.NameNotFoundException;
21import android.content.res.Resources;
22import android.os.Parcel;
23import android.os.Parcelable;
24import android.text.TextUtils;
25
26import com.android.internal.R;
27
28/**
29 * This class represents the attributes of a print job.
30 */
31public final class PrintAttributes implements Parcelable {
32    /** Duplex mode: No duplexing */
33    public static final int DUPLEX_MODE_NONE = 1 << 0;
34    /** Duplex mode: Turn a page along its long edge, e.g. like a book */
35    public static final int DUPLEX_MODE_LONG_EDGE = 1 << 1;
36    /** Duplex mode: Turn a page along its short edge, e.g. like a notepad */
37    public static final int DUPLEX_MODE_SHORT_EDGE = 1 << 2;
38
39
40    /** Orientation: Portrait page orientation. */
41    public static final int ORIENTATION_PORTRAIT = 1 << 0;
42    /** Orientation: Landscape page orientation. */
43    public static final int ORIENTATION_LANDSCAPE = 1 << 1;
44
45
46    /** Color mode: Monochrome color scheme, e.g. one color is used. */
47    public static final int COLOR_MODE_MONOCHROME = 1 << 0;
48    /** Color mode: Color color scheme, e.g. many colors are used. */
49    public static final int COLOR_MODE_COLOR = 1 << 1;
50
51
52    /** Fitting mode: No fitting. */
53    public static final int FITTING_MODE_NONE = 0x00000001;
54    /** Fitting mode: Fit the content to the page. */
55    public static final int FITTING_MODE_FIT_TO_PAGE = 0x00000002;
56
57
58    private static final int VALID_DUPLEX_MODES =
59            DUPLEX_MODE_NONE | DUPLEX_MODE_LONG_EDGE | DUPLEX_MODE_SHORT_EDGE;
60
61    private static final int VALID_COLOR_MODES =
62            COLOR_MODE_MONOCHROME | COLOR_MODE_COLOR;
63
64    private static final int VALID_FITTING_MODES =
65            FITTING_MODE_NONE | FITTING_MODE_FIT_TO_PAGE;
66
67    private static final int VALID_ORIENTATIONS =
68            ORIENTATION_PORTRAIT | ORIENTATION_LANDSCAPE;
69
70    private MediaSize mMediaSize;
71    private Resolution mResolution;
72    private Margins mMargins;
73    private Tray mInputTray;
74    private Tray mOutputTray;
75
76    private int mDuplexMode;
77    private int mColorMode;
78    private int mFittingMode;
79    private int mOrientation;
80    private int mCopies;
81
82    PrintAttributes() {
83        /* hide constructor */
84    }
85
86    private PrintAttributes(Parcel parcel) {
87        mMediaSize = (parcel.readInt() ==  1) ? MediaSize.createFromParcel(parcel) : null;
88        mResolution = (parcel.readInt() ==  1) ? Resolution.createFromParcel(parcel) : null;
89        mMargins = (parcel.readInt() ==  1) ? Margins.createFromParcel(parcel) : null;
90        mInputTray = (parcel.readInt() ==  1) ? Tray.createFromParcel(parcel) : null;
91        mOutputTray = (parcel.readInt() ==  1) ? Tray.createFromParcel(parcel) : null;
92        mDuplexMode = parcel.readInt();
93        mColorMode = parcel.readInt();
94        mFittingMode = parcel.readInt();
95        mOrientation = parcel.readInt();
96        mCopies = parcel.readInt();
97    }
98
99    /**
100     * Gets the media size.
101     *
102     * @return The media size or <code>null</code> if not set.
103     */
104    public MediaSize getMediaSize() {
105        return mMediaSize;
106    }
107
108    /**
109     * Sets the media size.
110     *
111     * @param The media size.
112     *
113     * @hide
114     */
115    public void setMediaSize(MediaSize mediaSize) {
116        mMediaSize = mediaSize;
117    }
118
119    /**
120     * Gets the resolution.
121     *
122     * @return The resolution or <code>null</code> if not set.
123     */
124    public Resolution getResolution() {
125        return mResolution;
126    }
127
128    /**
129     * Sets the resolution.
130     *
131     * @param The resolution.
132     *
133     * @hide
134     */
135    public void setResolution(Resolution resolution) {
136        mResolution = resolution;
137    }
138
139    /**
140     * Gets the margins.
141     *
142     * @return The margins or <code>null</code> if not set.
143     */
144    public Margins getMargins() {
145        return mMargins;
146    }
147
148    /**
149     * Sets the margins.
150     *
151     * @param The margins.
152     *
153     * @hide
154     */
155    public void setMargins(Margins margins) {
156        mMargins = margins;
157    }
158
159    /**
160     * Sets the input tray.
161     *
162     * @return The input tray or <code>null</code> if not set.
163     */
164    public Tray getInputTray() {
165        return mInputTray;
166    }
167
168    /**
169     * Gets the input tray.
170     *
171     * @param The input tray.
172     *
173     * @hide
174     */
175    public void setInputTray(Tray inputTray) {
176        mInputTray = inputTray;
177    }
178
179    /**
180     * Gets the output tray.
181     *
182     * @return The output tray or <code>null</code> if not set.
183     */
184    public Tray getOutputTray() {
185        return mOutputTray;
186    }
187
188    /**
189     * Sets the output tray.
190     *
191     * @param The output tray.
192     *
193     * @hide
194     */
195    public void setOutputTray(Tray outputTray) {
196        mOutputTray = outputTray;
197    }
198
199    /**
200     * Gets the duplex mode.
201     *
202     * @return The duplex mode or zero if not set.
203     *
204     * @see #DUPLEX_MODE_NONE
205     * @see #DUPLEX_MODE_SHORT_EDGE
206     * @see #DUPLEX_MODE_LONG_EDGE
207     */
208    public int getDuplexMode() {
209        return mDuplexMode;
210    }
211
212    /**
213     * Sets the duplex mode.
214     *
215     * @param The duplex mode.
216     *
217     * @hide
218     */
219    public void setDuplexMode(int duplexMode) {
220        enforceValidDuplexMode(duplexMode);
221        mDuplexMode = duplexMode;
222    }
223
224    /**
225     * Gets the color mode.
226     *
227     * @return The color mode or zero if not set.
228     *
229     * @see #COLOR_MODE_COLOR
230     * @see #COLOR_MODE_MONOCHROME
231     */
232    public int getColorMode() {
233        return mColorMode;
234    }
235
236    /**
237     * Sets the color mode.
238     *
239     * @param The color mode.
240     *
241     * @see #COLOR_MODE_MONOCHROME
242     * @see #COLOR_MODE_COLOR
243     *
244     * @hide
245     */
246    public void setColorMode(int colorMode) {
247        enforceValidColorMode(colorMode);
248        mColorMode = colorMode;
249    }
250
251    /**
252     * Gets the fitting mode.
253     *
254     * @return The fitting mode or zero if not set.
255     *
256     * @see #FITTING_MODE_NONE
257     * @see #FITTING_MODE_FIT_TO_PAGE
258     */
259    public int getFittingMode() {
260        return mFittingMode;
261    }
262
263    /**
264     * Sets the fitting mode.
265     *
266     * @param The fitting mode.
267     *
268     * @see #FITTING_MODE_NONE
269     * @see #FITTING_MODE_FIT_TO_PAGE
270     *
271     * @hide
272     */
273    public void setFittingMode(int fittingMode) {
274        enfoceValidFittingMode(fittingMode);
275        mFittingMode = fittingMode;
276    }
277
278    /**
279     * Gets the orientation.
280     *
281     * @return The orientation or zero if not set.
282     *
283     * @see #ORIENTATION_PORTRAIT
284     * @see #ORIENTATION_LANDSCAPE
285     */
286    public int getOrientation() {
287        return mOrientation;
288    }
289
290    /**
291     * Sets the orientation.
292     *
293     * @param The orientation.
294     *
295     * @see #ORIENTATION_PORTRAIT
296     * @see #ORIENTATION_LANDSCAPE
297     *
298     * @hide
299     */
300    public void setOrientation(int orientation) {
301        enforceValidOrientation(orientation);
302        mOrientation = orientation;
303    }
304
305    /**
306     * Gets the number of copies.
307     *
308     * @return The number of copies or zero if not set.
309     */
310    public int getCopies() {
311        return mCopies;
312    }
313
314    /**
315     * Sets the number of copies.
316     *
317     * @param copyCount The number of copies.
318     *
319     * @hide
320     */
321    public void setCopies(int copyCount) {
322        if (copyCount < 1) {
323            throw new IllegalArgumentException("Copies must be more than one.");
324        }
325        mCopies = copyCount;
326    }
327
328    @Override
329    public void writeToParcel(Parcel parcel, int flags) {
330        if (mMediaSize != null) {
331            parcel.writeInt(1);
332            mMediaSize.writeToParcel(parcel);
333        } else {
334            parcel.writeInt(0);
335        }
336        if (mResolution != null) {
337            parcel.writeInt(1);
338            mResolution.writeToParcel(parcel);
339        } else {
340            parcel.writeInt(0);
341        }
342        if (mMargins != null) {
343            parcel.writeInt(1);
344            mMargins.writeToParcel(parcel);
345        } else {
346            parcel.writeInt(0);
347        }
348        if (mInputTray != null) {
349            parcel.writeInt(1);
350            mInputTray.writeToParcel(parcel);
351        } else {
352            parcel.writeInt(0);
353        }
354        if (mOutputTray != null) {
355            parcel.writeInt(1);
356            mOutputTray.writeToParcel(parcel);
357        } else {
358            parcel.writeInt(0);
359        }
360        parcel.writeInt(mDuplexMode);
361        parcel.writeInt(mColorMode);
362        parcel.writeInt(mFittingMode);
363        parcel.writeInt(mOrientation);
364        parcel.writeInt(mCopies);
365    }
366
367    @Override
368    public int describeContents() {
369        return 0;
370    }
371
372    /** hide */
373    public void clear() {
374        mMediaSize = null;
375        mResolution = null;
376        mMargins = null;
377        mInputTray = null;
378        mOutputTray = null;
379        mDuplexMode = 0;
380        mColorMode = 0;
381        mFittingMode = 0;
382        mOrientation = 0;
383        mCopies = 0;
384    }
385
386    /**
387     * This class specifies a supported media size.
388     */
389    public static final class MediaSize {
390
391        // TODO: Verify media sizes and add more standard ones.
392
393        // ISO sizes
394
395        /**
396         * ISO A0 media size: 841mm x 1189mm (33.11" x 46.81")
397         *
398         * @see #createMediaSize(PackageManager, int)
399         */
400        public static final int ISO_A0 = 1;
401
402        /**
403         * ISO A1 media size: 594mm x 841mm (23.39" x 33.11")
404         *
405         * @see #createMediaSize(PackageManager, int)
406         */
407        public static final int ISO_A1 = 2;
408
409        /**
410         *
411         *ISO A2 media size: 420mm x 594mm (16.54" x 23.39")
412         *
413         * @see #createMediaSize(PackageManager, int)
414         */
415        public static final int ISO_A2 = 3;
416
417        /**
418         * ISO A3 media size: 297mm x 420mm (11.69" x 16.54")
419         *
420         * @see #createMediaSize(PackageManager, int)
421         */
422        public static final int ISO_A3 = 4;
423
424        /**
425         * ISO A4 media size: 210mm x 297mm (8.27" x 11.69")
426         *
427         * @see #createMediaSize(PackageManager, int)
428         */
429        public static final int ISO_A4 = 5;
430
431        /**
432         * ISO A5 media size: 148mm x 210mm (5.83" x 8.27")
433         *
434         * @see #createMediaSize(PackageManager, int)
435         */
436        public static final int ISO_A5 = 6;
437
438        /**
439         * ISO A6 media size: 105mm x 148mm (4.13" x 5.83")
440         *
441         * @see #createMediaSize(PackageManager, int)
442         */
443        public static final int ISO_A6 = 7;
444
445        /**
446         * ISO A7 media size: 74mm x 105mm (2.91" x 4.13")
447         *
448         * @see #createMediaSize(PackageManager, int)
449         */
450        public static final int ISO_A7 = 8;
451
452        /**
453         * ISO A8 media size: 52mm x 74mm (2.05" x 2.91")
454         *
455         * @see #createMediaSize(PackageManager, int)
456         */
457        public static final int ISO_A8 = 9;
458
459        /**
460         * ISO A9 media size: 37mm x 52mm (1.46" x 2.05")
461         *
462         * @see #createMediaSize(PackageManager, int)
463         */
464        public static final int ISO_A9 = 10;
465
466        /**
467         * ISO A10 media size: 26mm x 37mm (1.02" x 1.46")
468         *
469         * @see #createMediaSize(PackageManager, int)
470         */
471        public static final int ISO_A10 = 11;
472
473
474        /**
475         * ISO B0 media size: 1000mm x 1414mm (39.37" x 55.67")
476         *
477         * @see #createMediaSize(PackageManager, int)
478         */
479        public static final int ISO_B0 = 100;
480
481        /**
482         * ISO B1 media size: 707mm x 1000mm (27.83" x 39.37")
483         *
484         * @see #createMediaSize(PackageManager, int)
485         */
486        public static final int ISO_B1 = 101;
487
488        /**
489         * ISO B2 media size: 500mm x 707mm (19.69" x 27.83")
490         *
491         * @see #createMediaSize(PackageManager, int)
492         */
493        public static final int ISO_B2 = 102;
494
495        /**
496         * ISO B3 media size: 353mm x 500mm (13.90" x 19.69")
497         *
498         * @see #createMediaSize(PackageManager, int)
499         */
500        public static final int ISO_B3 = 103;
501
502        /**
503         * ISO B4 media size: 250mm x 353mm (9.84" x 13.90")
504         *
505         * @see #createMediaSize(PackageManager, int)
506         */
507        public static final int ISO_B4 = 104;
508
509        /**
510         * ISO B5 media size: 176mm x 250mm (6.93" x 9.84")
511         *
512         * @see #createMediaSize(PackageManager, int)
513         */
514        public static final int ISO_B5 = 105;
515
516        /**
517         * ISO B6 media size: 125mm x 176mm (4.92" x 6.93")
518         *
519         * @see #createMediaSize(PackageManager, int)
520         */
521        public static final int ISO_B6 = 106;
522
523        /**
524         * ISO B7 media size: 88mm x 125mm (3.46" x 4.92")
525         *
526         * @see #createMediaSize(PackageManager, int)
527         */
528        public static final int ISO_B7 = 107;
529
530        /** ISO B8 media size: 62mm x 88mm (2.44" x 3.46")
531         *
532         * @see #createMediaSize(PackageManager, int)
533         */
534        public static final int ISO_B8 = 108;
535
536        /**
537         * ISO B9 media size: 44mm x 62mm (1.73" x 2.44")
538         *
539         * @see #createMediaSize(PackageManager, int)
540         */
541        public static final int ISO_B9 = 109;
542
543        /**
544         * ISO B10 media size: 31mm x 44mm (1.22" x 1.73")
545         *
546         * @see #createMediaSize(PackageManager, int)
547         */
548        public static final int ISO_B10 = 110;
549
550
551        /**
552         * ISO C0 media size: 917mm x 1297mm (36.10" x 51.06")
553         *
554         * @see #createMediaSize(PackageManager, int)
555         */
556        public static final int ISO_C0 = 200;
557
558        /**
559         * ISO C1 media size: 648mm x 917mm (25.51" x 36.10")
560         *
561         * @see #createMediaSize(PackageManager, int)
562         */
563
564        public static final int ISO_C1 = 201;
565        /**
566         * ISO C2 media size: 458mm x 648mm (18.03" x 25.51")
567         *
568         * @see #createMediaSize(PackageManager, int)
569         */
570        public static final int ISO_C2 = 202;
571
572        /**
573         * ISO C3 media size: 324mm x 458mm (12.76" x 18.03")
574         *
575         * @see #createMediaSize(PackageManager, int)
576         */
577        public static final int ISO_C3 = 203;
578
579        /**
580         * ISO C4 media size: 229mm x 324mm (9.02" x 12.76")
581         *
582         * @see #createMediaSize(PackageManager, int)
583         */
584        public static final int ISO_C4 = 204;
585
586        /**
587         * ISO C5 media size: 162mm x 229mm (6.38" x 9.02")
588         *
589         * @see #createMediaSize(PackageManager, int)
590         */
591        public static final int ISO_C5 = 205;
592
593        /**
594         * ISO C6 media size: 114mm x 162mm (4.49" x 6.38")
595         *
596         * @see #createMediaSize(PackageManager, int)
597         */
598        public static final int ISO_C6 = 206;
599
600        /**
601         * ISO C7 media size: 81mm x 114mm (3.19" x 4.49")
602         *
603         * @see #createMediaSize(PackageManager, int)
604         */
605        public static final int ISO_C7 = 207;
606
607        /**
608         * ISO C8 media size: 57mm x 81mm (2.24" x 3.19")
609         *
610         * @see #createMediaSize(PackageManager, int)
611         */
612        public static final int ISO_C8 = 208;
613
614        /**
615         * ISO C9 media size: 40mm x 57mm (1.57" x 2.24")
616         *
617         * @see #createMediaSize(PackageManager, int)
618         */
619        public static final int ISO_C9 = 209;
620
621        /**
622         * ISO C10 media size: 28mm x 40mm (1.10" x 1.57")
623         *
624         * @see #createMediaSize(PackageManager, int)
625         */
626        public static final int ISO_C10 = 210;
627
628
629        // North America
630
631        /**
632         * North America Letter media size: 8.5" x 11"
633         *
634         * @see #createMediaSize(PackageManager, int)
635         */
636        public static final int NA_LETTER = 300;
637
638        /**
639         * North America Government-Letter media size: 8.0" x 10.5"
640         *
641         * @see #createMediaSize(PackageManager, int)
642         */
643        public static final int NA_GOVT_LETTER = 301;
644
645        /**
646         * North America Legal media size: 8.5" x 14"
647         *
648         * @see #createMediaSize(PackageManager, int)
649         */
650        public static final int NA_LEGAL = 302;
651
652        /**
653         * North America Junior Legal media size: 8.0" x 5.0"
654         *
655         * @see #createMediaSize(PackageManager, int)
656         */
657        public static final int NA_JUNIOR_LEGAL = 303;
658
659        /**
660         * North America Ledger media size: 17" x 11"
661         *
662         * @see #createMediaSize(PackageManager, int)
663         */
664        public static final int NA_LEDGER = 304;
665
666        /**
667         * North America Tabloid media size: 11" x 17"
668         *
669         * @see #createMediaSize(PackageManager, int)
670         */
671        public static final int NA_TBLOID = 305;
672
673        /**
674         * Creates a standard media size with a localized label.
675         *
676         * @param pm Package manager used to load the label.
677         * @param mediaSize Media size constant.
678         * @return A {@link MediaSize} instance with a localized label.
679         */
680        public static MediaSize createMediaSize(PackageManager pm, int mediaSize) {
681            final Resources resources;
682            try {
683                resources = pm.getResourcesForApplication("android");
684            } catch (NameNotFoundException nnfe) {
685                return null;
686            }
687            switch (mediaSize) {
688                case ISO_A0: {
689                    return new MediaSize("ISO_A0", resources
690                            .getString(R.string.mediaSize_iso_a0), 33110, 46810);
691                }
692                case ISO_A1: {
693                    return new MediaSize("ISO_A1", resources
694                            .getString(R.string.mediaSize_iso_a1), 23390, 33110);
695                }
696                case ISO_A2: {
697                    return new MediaSize("ISO_A2", resources
698                            .getString(R.string.mediaSize_iso_a2), 16540, 23390);
699                }
700                case ISO_A3: {
701                    return new MediaSize("ISO_A3", resources
702                            .getString(R.string.mediaSize_iso_a3), 11690, 16540);
703                }
704                case ISO_A4: {
705                    return new MediaSize("ISO_A4", resources
706                            .getString(R.string.mediaSize_iso_a4), 8270, 11690);
707                }
708                case ISO_A5: {
709                    return new MediaSize("ISO_A5", resources
710                            .getString(R.string.mediaSize_iso_a5), 5830, 8270);
711                }
712                case ISO_A6: {
713                    return new MediaSize("ISO_A6", resources
714                            .getString(R.string.mediaSize_iso_a6), 4130, 5830);
715                }
716                case ISO_A7: {
717                    return new MediaSize("ISO_A7", resources
718                            .getString(R.string.mediaSize_iso_a7), 2910, 4130);
719                }
720                case ISO_A8: {
721                    return new MediaSize("ISO_A8", resources
722                            .getString(R.string.mediaSize_iso_a8), 2050, 2910);
723                }
724                case ISO_A9: {
725                    return new MediaSize("ISO_A9", resources
726                            .getString(R.string.mediaSize_iso_a9), 1460, 2050);
727                }
728                case ISO_A10: {
729                    return new MediaSize("ISO_A10", resources
730                            .getString(R.string.mediaSize_iso_a10), 1020, 1460);
731                }
732                case ISO_B0: {
733                    return new MediaSize("ISO_B0", resources
734                            .getString(R.string.mediaSize_iso_b0), 39370, 55670);
735                }
736                case ISO_B1: {
737                    return new MediaSize("ISO_B1", resources
738                            .getString(R.string.mediaSize_iso_b1), 27830, 39370);
739                }
740                case ISO_B2: {
741                    return new MediaSize("ISO_B2", resources
742                            .getString(R.string.mediaSize_iso_b2), 19690, 27830);
743                }
744                case ISO_B3: {
745                    return new MediaSize("ISO_B3", resources
746                            .getString(R.string.mediaSize_iso_b3), 13900, 19690);
747                }
748                case ISO_B4: {
749                    return new MediaSize("ISO_B4", resources
750                            .getString(R.string.mediaSize_iso_b4), 9840, 13900);
751                }
752                case ISO_B5: {
753                    return new MediaSize("ISO_B5", resources
754                            .getString(R.string.mediaSize_iso_b5), 6930, 9840);
755                }
756                case ISO_B6: {
757                    return new MediaSize("ISO_B6", resources
758                            .getString(R.string.mediaSize_iso_b6), 4920, 6930);
759                }
760                case ISO_B7: {
761                    return new MediaSize("ISO_B7", resources
762                            .getString(R.string.mediaSize_iso_b7), 3460, 4920);
763                }
764                case ISO_B8: {
765                    return new MediaSize("ISO_B8", resources
766                            .getString(R.string.mediaSize_iso_b8), 2440, 3460);
767                }
768                case ISO_B9: {
769                    return new MediaSize("ISO_B9", resources
770                            .getString(R.string.mediaSize_iso_b9), 1730, 2440);
771                }
772                case ISO_B10: {
773                    return new MediaSize("ISO_B10", resources
774                            .getString(R.string.mediaSize_iso_b10), 1220, 1730);
775                }
776                case ISO_C0: {
777                    return new MediaSize("ISO_C0", resources
778                            .getString(R.string.mediaSize_iso_c0), 36100, 51060);
779                }
780                case ISO_C1: {
781                    return new MediaSize("ISO_C1", resources
782                            .getString(R.string.mediaSize_iso_c1), 25510, 36100);
783                }
784                case ISO_C2: {
785                    return new MediaSize("ISO_C2", resources
786                            .getString(R.string.mediaSize_iso_c2), 18030, 25510);
787                }
788                case ISO_C3: {
789                    return new MediaSize("ISO_C3", resources
790                            .getString(R.string.mediaSize_iso_c3), 12760, 18030);
791                }
792                case ISO_C4: {
793                    return new MediaSize("ISO_C4", resources
794                            .getString(R.string.mediaSize_iso_c4), 9020, 12760);
795                }
796                case ISO_C5: {
797                    return new MediaSize("ISO_C5", resources
798                            .getString(R.string.mediaSize_iso_c5), 6380, 9020);
799                }
800                case ISO_C6: {
801                    return new MediaSize("ISO_C6", resources
802                            .getString(R.string.mediaSize_iso_c6), 4490, 6380);
803                }
804                case ISO_C7: {
805                    return new MediaSize("ISO_C7", resources
806                            .getString(R.string.mediaSize_iso_c7), 3190, 4490);
807                }
808                case ISO_C8: {
809                    return new MediaSize("ISO_C8", resources
810                            .getString(R.string.mediaSize_iso_c8), 2240, 3190);
811                }
812                case ISO_C9: {
813                    return new MediaSize("ISO_C9", resources
814                            .getString(R.string.mediaSize_iso_c9), 1570, 2240);
815                }
816                case ISO_C10: {
817                    return new MediaSize("ISO_C10", resources
818                            .getString(R.string.mediaSize_iso_c10), 1100, 1570);
819                }
820                case NA_LETTER: {
821                    return new MediaSize("NA_LETTER", resources
822                            .getString(R.string.mediaSize_na_letter), 8500, 11000);
823                }
824                case NA_GOVT_LETTER: {
825                    return new MediaSize("NA_GOVT_LETTER", resources
826                            .getString(R.string.mediaSize_na_gvrnmt_letter), 8000, 10500);
827                }
828                case NA_LEGAL: {
829                    return new MediaSize("NA_LEGAL", resources
830                            .getString(R.string.mediaSize_na_legal), 8500, 14000);
831                }
832                case NA_JUNIOR_LEGAL: {
833                    return new MediaSize("NA_JUNIOR_LEGAL", resources
834                            .getString(R.string.mediaSize_na_junior_legal), 8000, 5000);
835                }
836                case NA_LEDGER: {
837                    return new MediaSize("NA_LEDGER", resources
838                            .getString(R.string.mediaSize_na_ledger), 17000, 11000);
839                }
840                case NA_TBLOID: {
841                    return new MediaSize("NA_TABLOID", resources
842                            .getString(R.string.mediaSize_na_tabloid), 11000, 17000);
843                }
844                default: {
845                    throw new IllegalArgumentException("Unknown media size.");
846                }
847            }
848        }
849
850        private final String mId;
851        private final CharSequence mLabel;
852        private final int mWidthMils;
853        private final int mHeightMils;
854
855        /**
856         * Creates a new instance.
857         *
858         * @param id The unique media size id.
859         * @param label The <strong>internationalized</strong> human readable label.
860         * @param widthMils The width in mils (thousands of an inch).
861         * @param heightMils The height in mils (thousands of an inch).
862         *
863         * @throws IllegalArgumentException If the id is empty.
864         * @throws IllegalArgumentException If the label is empty.
865         * @throws IllegalArgumentException If the widthMils is less than or equal to zero.
866         * @throws IllegalArgumentException If the heightMils is less than or equal to zero.
867         */
868        public MediaSize(String id, CharSequence label, int widthMils, int heightMils) {
869            if (TextUtils.isEmpty(id)) {
870                throw new IllegalArgumentException("id cannot be empty.");
871            }
872            if (TextUtils.isEmpty(label)) {
873                throw new IllegalArgumentException("label cannot be empty.");
874            }
875            if (widthMils <= 0) {
876                throw new IllegalArgumentException("widthMils "
877                        + "cannot be less than or equal to zero.");
878            }
879            if (heightMils <= 0) {
880                throw new IllegalArgumentException("heightMils "
881                       + "cannot be less than or euqual to zero.");
882            }
883            mId = id;
884            mLabel = label;
885            mWidthMils = widthMils;
886            mHeightMils = heightMils;
887        }
888
889        /**
890         * Gets the unique media size id.
891         *
892         * @return The unique media size id.
893         */
894        public String getId() {
895            return mId;
896        }
897
898        /**
899         * Gets the human readable media size label.
900         *
901         * @return The human readable label.
902         */
903        public CharSequence getLabel() {
904            return mLabel;
905        }
906
907        /**
908         * Gets the media width in mils (thousands of an inch).
909         *
910         * @return The media width.
911         */
912        public int getWidthMils() {
913            return mWidthMils;
914        }
915
916        /**
917         * Gets the media height in mils (thousands of an inch).
918         *
919         * @return The media height.
920         */
921        public int getHeightMils() {
922            return mHeightMils;
923        }
924
925        void writeToParcel(Parcel parcel) {
926            parcel.writeString(mId);
927            parcel.writeCharSequence(mLabel);
928            parcel.writeInt(mWidthMils);
929            parcel.writeInt(mHeightMils);
930        }
931
932        static MediaSize createFromParcel(Parcel parcel) {
933            return new MediaSize(
934                    parcel.readString(),
935                    parcel.readCharSequence(),
936                    parcel.readInt(),
937                    parcel.readInt());
938        }
939
940        @Override
941        public String toString() {
942            StringBuilder builder = new StringBuilder();
943            builder.append("MediaSize{");
944            builder.append("id: ").append(mId);
945            builder.append(", label: ").append(mLabel);
946            builder.append(", heightMils: ").append(mHeightMils);
947            builder.append(", widthMils: ").append(mWidthMils);
948            builder.append("}");
949            return builder.toString();
950        }
951    }
952
953    /**
954     * This class specifies a supported resolution in dpi (dots per inch).
955     */
956    public static final class Resolution {
957        private final String mId;
958        private final CharSequence mLabel;
959        private final int mHorizontalDpi;
960        private final int mVerticalDpi;
961
962        /**
963         * Creates a new instance.
964         *
965         * @param id The unique resolution id.
966         * @param label The <strong>internationalized</strong> human readable label.
967         * @param horizontalDpi The horizontal resolution in dpi.
968         * @param verticalDpi The vertical resolution in dpi.
969         *
970         * @throws IllegalArgumentException If the id is empty.
971         * @throws IllegalArgumentException If the label is empty.
972         * @throws IllegalArgumentException If the horizontalDpi is less than or equal to zero.
973         * @throws IllegalArgumentException If the verticalDpi is less than or equal to zero.
974         */
975        public Resolution(String id, CharSequence label, int horizontalDpi, int verticalDpi) {
976            if (TextUtils.isEmpty(id)) {
977                throw new IllegalArgumentException("id cannot be empty.");
978            }
979            if (TextUtils.isEmpty(label)) {
980                throw new IllegalArgumentException("label cannot be empty.");
981            }
982            if (horizontalDpi <= 0) {
983                throw new IllegalArgumentException("horizontalDpi "
984                        + "cannot be less than or equal to zero.");
985            }
986            if (verticalDpi <= 0) {
987                throw new IllegalArgumentException("verticalDpi"
988                       + " cannot be less than or equal to zero.");
989            }
990            mId = id;
991            mLabel = label;
992            mHorizontalDpi = horizontalDpi;
993            mVerticalDpi = verticalDpi;
994        }
995
996        /**
997         * Gets the unique resolution id.
998         *
999         * @return The unique resolution id.
1000         */
1001        public String getId() {
1002            return mId;
1003        }
1004
1005        /**
1006         * Gets the resolution human readable label.
1007         *
1008         * @return The human readable label.
1009         */
1010        public CharSequence getLabel(PackageManager packageManager) {
1011            return mLabel;
1012        }
1013
1014        /**
1015         * Gets the horizontal resolution in dpi.
1016         *
1017         * @return The horizontal resolution.
1018         */
1019        public int getHorizontalDpi() {
1020            return mHorizontalDpi;
1021        }
1022
1023        /**
1024         * Gets the vertical resolution in dpi.
1025         *
1026         * @return The vertical resolution.
1027         */
1028        public int getVerticalDpi() {
1029            return mVerticalDpi;
1030        }
1031
1032        void writeToParcel(Parcel parcel) {
1033            parcel.writeString(mId);
1034            parcel.writeCharSequence(mLabel);
1035            parcel.writeInt(mHorizontalDpi);
1036            parcel.writeInt(mVerticalDpi);
1037        }
1038
1039        static Resolution createFromParcel(Parcel parcel) {
1040            return new Resolution(
1041                    parcel.readString(),
1042                    parcel.readCharSequence(),
1043                    parcel.readInt(),
1044                    parcel.readInt());
1045        }
1046
1047        @Override
1048        public String toString() {
1049            StringBuilder builder = new StringBuilder();
1050            builder.append("Resolution{");
1051            builder.append("id: ").append(mId);
1052            builder.append(", label: ").append(mLabel);
1053            builder.append(", horizontalDpi: ").append(mHorizontalDpi);
1054            builder.append(", verticalDpi: ").append(mVerticalDpi);
1055            builder.append("}");
1056            return builder.toString();
1057        }
1058    }
1059
1060    /**
1061     * This class specifies content margins.
1062     */
1063    public static final class Margins {
1064        private final int mLeftMils;
1065        private final int mTopMils;
1066        private final int mRightMils;
1067        private final int mBottomMils;
1068
1069        /**
1070         * Creates a new instance.
1071         *
1072         * @param leftMils The left margin in mils (thousands of an inch).
1073         * @param topMils The top margin in mils (thousands of an inch).
1074         * @param rightMils The right margin in mils (thousands of an inch).
1075         * @param bottomMils The bottom margin in mils (thousands of an inch).
1076         *
1077         * @throws IllegalArgumentException If the leftMils is less than zero.
1078         * @throws IllegalArgumentException If the topMils is less than zero.
1079         * @throws IllegalArgumentException If the rightMils is less than zero.
1080         * @throws IllegalArgumentException If the bottomMils is less than zero.
1081         */
1082        public Margins(int leftMils, int topMils, int rightMils, int bottomMils) {
1083            if (leftMils < 0) {
1084                throw new IllegalArgumentException("leftMils cannot be less than zero.");
1085            }
1086            if (topMils < 0) {
1087                throw new IllegalArgumentException("topMils cannot be less than zero.");
1088            }
1089            if (rightMils < 0) {
1090                throw new IllegalArgumentException("rightMils cannot be less than zero.");
1091            }
1092            if (bottomMils < 0) {
1093                throw new IllegalArgumentException("bottomMils cannot be less than zero.");
1094            }
1095            mTopMils = topMils;
1096            mLeftMils = leftMils;
1097            mRightMils = rightMils;
1098            mBottomMils = bottomMils;
1099        }
1100
1101        /**
1102         * Gets the left margin in mils (thousands of an inch).
1103         *
1104         * @return The left margin.
1105         */
1106        public int getLeftMils() {
1107            return mLeftMils;
1108        }
1109
1110        /**
1111         * Gets the top margin in mils (thousands of an inch).
1112         *
1113         * @return The top margin.
1114         */
1115        public int getTopMils() {
1116            return mTopMils;
1117        }
1118
1119        /**
1120         * Gets the right margin in mils (thousands of an inch).
1121         *
1122         * @return The right margin.
1123         */
1124        public int getRightMils() {
1125            return mRightMils;
1126        }
1127
1128        /**
1129         * Gets the bottom margin in mils (thousands of an inch).
1130         *
1131         * @return The bottom margin.
1132         */
1133        public int getBottomMils() {
1134            return mBottomMils;
1135        }
1136
1137        void writeToParcel(Parcel parcel) {
1138            parcel.writeInt(mLeftMils);
1139            parcel.writeInt(mTopMils);
1140            parcel.writeInt(mRightMils);
1141            parcel.writeInt(mBottomMils);
1142        }
1143
1144        static Margins createFromParcel(Parcel parcel) {
1145            return new Margins(
1146                    parcel.readInt(),
1147                    parcel.readInt(),
1148                    parcel.readInt(),
1149                    parcel.readInt());
1150        }
1151
1152        @Override
1153        public String toString() {
1154            StringBuilder builder = new StringBuilder();
1155            builder.append("Margins{");
1156            builder.append("leftMils: ").append(mLeftMils);
1157            builder.append(", topMils: ").append(mTopMils);
1158            builder.append(", rightMils: ").append(mRightMils);
1159            builder.append(", bottomMils: ").append(mBottomMils);
1160            builder.append("}");
1161            return builder.toString();
1162        }
1163    }
1164
1165    /**
1166     * Represents a printer tray.
1167     */
1168    public static final class Tray {
1169        private final String mId;
1170        private final CharSequence mLabel;
1171
1172        /**
1173         * Creates a new instance.
1174         *
1175         * @param id The unique tray id.
1176         * @param label The <strong>internationalized</strong> human readable label.
1177         *
1178         * @throws IllegalArgumentException If the id is empty.
1179         * @throws IllegalArgumentException If the label is empty.
1180         */
1181        public Tray(String id, CharSequence label) {
1182            if (TextUtils.isEmpty(id)) {
1183                throw new IllegalArgumentException("id cannot be empty.");
1184            }
1185            if (TextUtils.isEmpty(label)) {
1186                throw new IllegalArgumentException("label cannot be empty.");
1187            }
1188            mId = id;
1189            mLabel = label;
1190        }
1191
1192        /**
1193         * Gets the unique tray id.
1194         *
1195         * @return The unique tray id.
1196         */
1197        public String getId() {
1198            return mId;
1199        }
1200
1201        /**
1202         * Gets the tray human readable label.
1203         *
1204         * @return The human readable label.
1205         */
1206        public CharSequence getLabel(PackageManager packageManager) {
1207            return mLabel;
1208        }
1209
1210        void writeToParcel(Parcel parcel) {
1211            parcel.writeString(mId);
1212            parcel.writeCharSequence(mLabel);
1213        }
1214
1215        static Tray createFromParcel(Parcel parcel) {
1216            return new Tray(
1217                    parcel.readString(),
1218                    parcel.readCharSequence());
1219        }
1220
1221        @Override
1222        public String toString() {
1223            StringBuilder builder = new StringBuilder();
1224            builder.append("Tray{");
1225            builder.append("id: ").append(mId);
1226            builder.append("id: ").append(mId);
1227            builder.append(", label: ").append(mLabel);
1228            builder.append("}");
1229            return builder.toString();
1230        }
1231    }
1232
1233    @Override
1234    public String toString() {
1235        StringBuilder builder = new StringBuilder();
1236        builder.append("PrintAttributes{");
1237        builder.append("mediaSize: ").append(mMediaSize);
1238        builder.append(", resolution: ").append(mResolution);
1239        builder.append(", margins: ").append(mMargins);
1240        builder.append(", duplexMode: ").append(duplexModeToString(mDuplexMode));
1241        builder.append(", colorMode: ").append(colorModeToString(mColorMode));
1242        builder.append(", fittingMode: ").append(fittingModeToString(mFittingMode));
1243        builder.append(", orientation: ").append(orientationToString(mOrientation));
1244        builder.append(", copies: ").append(mCopies);
1245        return builder.toString();
1246    }
1247
1248    private static String duplexModeToString(int duplexMode) {
1249        switch (duplexMode) {
1250            case DUPLEX_MODE_NONE: {
1251                return "DUPLEX_MODE_NONE";
1252            }
1253            case DUPLEX_MODE_LONG_EDGE: {
1254                return "DUPLEX_MODE_LONG_EDGE";
1255            }
1256            case DUPLEX_MODE_SHORT_EDGE: {
1257                return "DUPLEX_MODE_SHORT_EDGE";
1258            }
1259            default:
1260                return "DUPLEX_MODE_UNKNOWN";
1261        }
1262    }
1263
1264    private static String colorModeToString(int colorMode) {
1265        switch (colorMode) {
1266            case COLOR_MODE_MONOCHROME: {
1267                return "COLOR_MODE_MONOCHROME";
1268            }
1269            case COLOR_MODE_COLOR: {
1270                return "COLOR_MODE_COLOR";
1271            }
1272            default:
1273                return "COLOR_MODE_UNKNOWN";
1274        }
1275    }
1276
1277    private static String orientationToString(int orientation) {
1278        switch (orientation) {
1279            case ORIENTATION_PORTRAIT: {
1280                return "ORIENTATION_PORTRAIT";
1281            }
1282            case ORIENTATION_LANDSCAPE: {
1283                return "ORIENTATION_LANDSCAPE";
1284            }
1285            default:
1286                return "ORIENTATION_UNKNOWN";
1287        }
1288    }
1289
1290    private static String fittingModeToString(int fittingMode) {
1291        switch (fittingMode) {
1292            case FITTING_MODE_NONE: {
1293                return "FITTING_MODE_NONE";
1294            }
1295            case FITTING_MODE_FIT_TO_PAGE: {
1296                return "FITTING_MODE_FIT_TO_PAGE";
1297            }
1298            default:
1299                return "FITTING_MODE_UNKNOWN";
1300        }
1301    }
1302
1303    static void enforceValidDuplexMode(int duplexMode) {
1304        if ((duplexMode & VALID_DUPLEX_MODES) == 0) {
1305            throw new IllegalArgumentException("invalid duplex mode: " + duplexMode);
1306        }
1307    }
1308
1309    static void enforceValidColorMode(int colorMode) {
1310        if ((colorMode & VALID_COLOR_MODES) == 0) {
1311            throw new IllegalArgumentException("invalid color mode: " + colorMode);
1312        }
1313    }
1314
1315    static void enfoceValidFittingMode(int fittingMode) {
1316        if ((fittingMode & VALID_FITTING_MODES) == 0) {
1317            throw new IllegalArgumentException("invalid fitting mode: " + fittingMode);
1318        }
1319    }
1320
1321    static void enforceValidOrientation(int orientation) {
1322        if ((orientation & VALID_ORIENTATIONS) == 0) {
1323            throw new IllegalArgumentException("invalid orientation: " + orientation);
1324        }
1325    }
1326
1327    /**
1328     * Builder for creating {@link PrintAttributes}.
1329     */
1330    public static final class Builder {
1331        private final PrintAttributes mAttributes = new PrintAttributes();
1332
1333        /**
1334         * Sets the media size.
1335         *
1336         * @param mediaSize The media size.
1337         * @return This builder.
1338         */
1339        public Builder setMediaSize(MediaSize mediaSize) {
1340            mAttributes.setMediaSize(mediaSize);
1341            return this;
1342        }
1343
1344        /**
1345         * Sets the resolution.
1346         *
1347         * @param resolution The resolution.
1348         * @return This builder.
1349         */
1350        public Builder setResolution(Resolution resolution) {
1351            mAttributes.setResolution(resolution);
1352            return this;
1353        }
1354
1355        /**
1356         * Sets the margins.
1357         *
1358         * @param margins The margins.
1359         * @return This builder.
1360         */
1361        public Builder setMargins(Margins margins) {
1362            mAttributes.setMargins(margins);
1363            return this;
1364        }
1365
1366        /**
1367         * Sets the input tray.
1368         *
1369         * @param inputTray The tray.
1370         * @return This builder.
1371         */
1372        public Builder setInputTray(Tray inputTray) {
1373            mAttributes.setInputTray(inputTray);
1374            return this;
1375        }
1376
1377        /**
1378         * Sets the output tray.
1379         *
1380         * @param outputTray The tray.
1381         * @return This builder.
1382         */
1383        public Builder setOutputTray(Tray outputTray) {
1384            mAttributes.setOutputTray(outputTray);
1385            return this;
1386        }
1387
1388        /**
1389         * Sets the duplex mode.
1390         *
1391         * @param duplexMode A valid duplex mode or zero.
1392         * @return This builder.
1393         *
1394         * @see PrintAttributes#DUPLEX_MODE_NONE
1395         * @see PrintAttributes#DUPLEX_MODE_SHORT_EDGE
1396         * @see PrintAttributes#DUPLEX_MODE_LONG_EDGE
1397         */
1398        public Builder setDuplexMode(int duplexMode) {
1399            if (Integer.bitCount(duplexMode) != 1) {
1400                throw new IllegalArgumentException("can specify at most one duplexMode bit.");
1401            }
1402            mAttributes.setDuplexMode(duplexMode);
1403            return this;
1404        }
1405
1406        /**
1407         * Sets the color mode.
1408         *
1409         * @param colorMode A valid color mode or zero.
1410         * @return This builder.
1411         *
1412         * @see PrintAttributes#COLOR_MODE_MONOCHROME
1413         * @see PrintAttributes#COLOR_MODE_COLOR
1414         */
1415        public Builder setColorMode(int colorMode) {
1416            if (Integer.bitCount(colorMode) > 1) {
1417                throw new IllegalArgumentException("can specify at most one colorMode bit.");
1418            }
1419            mAttributes.setColorMode(colorMode);
1420            return this;
1421        }
1422
1423        /**
1424         * Sets the fitting mode.
1425         *
1426         * @param fittingMode A valid fitting mode or zero.
1427         * @return This builder.
1428         *
1429         * @see PrintAttributes#FITTING_MODE_NONE
1430         * @see PrintAttributes#FITTING_MODE_FIT_TO_PAGE
1431         */
1432        public Builder setFittingMode(int fittingMode) {
1433            if (Integer.bitCount(fittingMode) > 1) {
1434                throw new IllegalArgumentException("can specify at most one fittingMode bit.");
1435            }
1436            mAttributes.setFittingMode(fittingMode);
1437            return this;
1438        }
1439
1440        /**
1441         * Sets the orientation.
1442         *
1443         * @param orientation A valid orientation or zero.
1444         * @return This builder.
1445         *
1446         * @see PrintAttributes#ORIENTATION_PORTRAIT
1447         * @see PrintAttributes#ORIENTATION_LANDSCAPE
1448         */
1449        public Builder setOrientation(int orientation) {
1450            if (Integer.bitCount(orientation) > 1) {
1451                throw new IllegalArgumentException("can specify at most one orientation bit.");
1452            }
1453            mAttributes.setOrientation(orientation);
1454            return this;
1455        }
1456
1457        /**
1458         * Sets the number of copies.
1459         *
1460         * @param copyCount A greater or equal to zero copy count.
1461         * @return This builder.
1462         */
1463        public Builder setCopyCount(int copyCount) {
1464            mAttributes.setCopies(copyCount);
1465            return this;
1466        }
1467
1468        /**
1469         * Creates a new {@link PrintAttributes} instance.
1470         *
1471         * @return The new instance.
1472         */
1473        public PrintAttributes create() {
1474            return mAttributes;
1475        }
1476    }
1477
1478    public static final Parcelable.Creator<PrintAttributes> CREATOR =
1479            new Creator<PrintAttributes>() {
1480        @Override
1481        public PrintAttributes createFromParcel(Parcel parcel) {
1482            return new PrintAttributes(parcel);
1483        }
1484
1485        @Override
1486        public PrintAttributes[] newArray(int size) {
1487            return new PrintAttributes[size];
1488        }
1489    };
1490}
1491