blob: b1e427ed3d3430b543a62efefecb5a45f3409841 [file] [log] [blame]
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -07001/*
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;
Svetoslav773f54d2013-09-03 14:01:43 -070021import android.content.res.Resources.NotFoundException;
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -070022import android.os.Parcel;
23import android.os.Parcelable;
24import android.text.TextUtils;
Svetoslav773f54d2013-09-03 14:01:43 -070025import android.util.Log;
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -070026
27import com.android.internal.R;
28
29/**
30 * This class represents the attributes of a print job.
31 */
32public final class PrintAttributes implements Parcelable {
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -070033
34 /** Color mode: Monochrome color scheme, e.g. one color is used. */
35 public static final int COLOR_MODE_MONOCHROME = 1 << 0;
36 /** Color mode: Color color scheme, e.g. many colors are used. */
37 public static final int COLOR_MODE_COLOR = 1 << 1;
38
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -070039 private static final int VALID_COLOR_MODES =
40 COLOR_MODE_MONOCHROME | COLOR_MODE_COLOR;
41
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -070042 private MediaSize mMediaSize;
43 private Resolution mResolution;
44 private Margins mMargins;
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -070045
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -070046 private int mColorMode;
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -070047
48 PrintAttributes() {
49 /* hide constructor */
50 }
51
52 private PrintAttributes(Parcel parcel) {
53 mMediaSize = (parcel.readInt() == 1) ? MediaSize.createFromParcel(parcel) : null;
54 mResolution = (parcel.readInt() == 1) ? Resolution.createFromParcel(parcel) : null;
55 mMargins = (parcel.readInt() == 1) ? Margins.createFromParcel(parcel) : null;
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -070056 mColorMode = parcel.readInt();
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -070057 }
58
59 /**
60 * Gets the media size.
61 *
62 * @return The media size or <code>null</code> if not set.
63 */
64 public MediaSize getMediaSize() {
65 return mMediaSize;
66 }
67
68 /**
69 * Sets the media size.
70 *
71 * @param The media size.
72 *
73 * @hide
74 */
75 public void setMediaSize(MediaSize mediaSize) {
76 mMediaSize = mediaSize;
77 }
78
79 /**
80 * Gets the resolution.
81 *
82 * @return The resolution or <code>null</code> if not set.
83 */
84 public Resolution getResolution() {
85 return mResolution;
86 }
87
88 /**
89 * Sets the resolution.
90 *
91 * @param The resolution.
92 *
93 * @hide
94 */
95 public void setResolution(Resolution resolution) {
96 mResolution = resolution;
97 }
98
99 /**
100 * Gets the margins.
101 *
102 * @return The margins or <code>null</code> if not set.
103 */
104 public Margins getMargins() {
105 return mMargins;
106 }
107
108 /**
109 * Sets the margins.
110 *
111 * @param The margins.
112 *
113 * @hide
114 */
115 public void setMargins(Margins margins) {
116 mMargins = margins;
117 }
118
119 /**
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700120 * Gets the color mode.
121 *
122 * @return The color mode or zero if not set.
123 *
124 * @see #COLOR_MODE_COLOR
125 * @see #COLOR_MODE_MONOCHROME
126 */
127 public int getColorMode() {
128 return mColorMode;
129 }
130
131 /**
132 * Sets the color mode.
133 *
134 * @param The color mode.
135 *
136 * @see #COLOR_MODE_MONOCHROME
137 * @see #COLOR_MODE_COLOR
138 *
139 * @hide
140 */
141 public void setColorMode(int colorMode) {
142 enforceValidColorMode(colorMode);
143 mColorMode = colorMode;
144 }
145
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700146 @Override
147 public void writeToParcel(Parcel parcel, int flags) {
148 if (mMediaSize != null) {
149 parcel.writeInt(1);
150 mMediaSize.writeToParcel(parcel);
151 } else {
152 parcel.writeInt(0);
153 }
154 if (mResolution != null) {
155 parcel.writeInt(1);
156 mResolution.writeToParcel(parcel);
157 } else {
158 parcel.writeInt(0);
159 }
160 if (mMargins != null) {
161 parcel.writeInt(1);
162 mMargins.writeToParcel(parcel);
163 } else {
164 parcel.writeInt(0);
165 }
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700166 parcel.writeInt(mColorMode);
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700167 }
168
169 @Override
170 public int describeContents() {
171 return 0;
172 }
173
Svetoslav Ganov85b1f882013-07-24 17:00:06 -0700174 @Override
175 public int hashCode() {
176 final int prime = 31;
177 int result = 1;
178 result = prime * result + mColorMode;
Svetoslav Ganov85b1f882013-07-24 17:00:06 -0700179 result = prime * result + ((mMargins == null) ? 0 : mMargins.hashCode());
180 result = prime * result + ((mMediaSize == null) ? 0 : mMediaSize.hashCode());
Svetoslav Ganov85b1f882013-07-24 17:00:06 -0700181 result = prime * result + ((mResolution == null) ? 0 : mResolution.hashCode());
182 return result;
183 }
184
185 @Override
186 public boolean equals(Object obj) {
187 if (this == obj) {
188 return true;
189 }
190 if (obj == null) {
191 return false;
192 }
193 if (getClass() != obj.getClass()) {
194 return false;
195 }
196 PrintAttributes other = (PrintAttributes) obj;
197 if (mColorMode != other.mColorMode) {
198 return false;
199 }
Svetoslav Ganov85b1f882013-07-24 17:00:06 -0700200 if (mMargins == null) {
201 if (other.mMargins != null) {
202 return false;
203 }
204 } else if (!mMargins.equals(other.mMargins)) {
205 return false;
206 }
207 if (mMediaSize == null) {
208 if (other.mMediaSize != null) {
209 return false;
210 }
211 } else if (!mMediaSize.equals(other.mMediaSize)) {
212 return false;
213 }
214 if (mResolution == null) {
215 if (other.mResolution != null) {
216 return false;
217 }
218 } else if (!mResolution.equals(other.mResolution)) {
219 return false;
220 }
221 return true;
222 }
223
224 @Override
225 public String toString() {
226 StringBuilder builder = new StringBuilder();
227 builder.append("PrintAttributes{");
228 builder.append("mediaSize: ").append(mMediaSize);
229 builder.append(", resolution: ").append(mResolution);
230 builder.append(", margins: ").append(mMargins);
Svetoslav Ganov85b1f882013-07-24 17:00:06 -0700231 builder.append(", colorMode: ").append(colorModeToString(mColorMode));
Svetoslav Ganov85b1f882013-07-24 17:00:06 -0700232 builder.append("}");
233 return builder.toString();
234 }
235
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700236 /** hide */
237 public void clear() {
238 mMediaSize = null;
239 mResolution = null;
240 mMargins = null;
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700241 mColorMode = 0;
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700242 }
243
244 /**
Svetoslav Ganov0d1daa52013-07-23 13:29:31 -0700245 * @hide
246 */
247 public void copyFrom(PrintAttributes other) {
248 mMediaSize = other.mMediaSize;
249 mResolution = other.mResolution;
250 mMargins = other.mMargins;
Svetoslav Ganov0d1daa52013-07-23 13:29:31 -0700251 mColorMode = other.mColorMode;
Svetoslav Ganov0d1daa52013-07-23 13:29:31 -0700252 }
253
254 /**
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700255 * This class specifies a supported media size.
256 */
257 public static final class MediaSize {
Svetoslav773f54d2013-09-03 14:01:43 -0700258 private static final String LOG_TAG = "MediaSize";
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700259
260 // TODO: Verify media sizes and add more standard ones.
261
262 // ISO sizes
263
Svetoslav773f54d2013-09-03 14:01:43 -0700264 /** ISO A0 media size: 841mm x 1189mm (33.11" x 46.81") */
265 public static final MediaSize ISO_A0 =
266 new MediaSize("ISO_A0", "android", R.string.mediaSize_iso_a0, 33110, 46810);
267 /** ISO A1 media size: 594mm x 841mm (23.39" x 33.11") */
268 public static final MediaSize ISO_A1 =
269 new MediaSize("ISO_A1", "android", R.string.mediaSize_iso_a1, 23390, 33110);
270 /** ISO A2 media size: 420mm x 594mm (16.54" x 23.39") */
271 public static final MediaSize ISO_A2 =
272 new MediaSize("ISO_A2", "android", R.string.mediaSize_iso_a2, 16540, 23390);
273 /** ISO A3 media size: 297mm x 420mm (11.69" x 16.54") */
274 public static final MediaSize ISO_A3 =
275 new MediaSize("ISO_A3", "android", R.string.mediaSize_iso_a3, 11690, 16540);
276 /** ISO A4 media size: 210mm x 297mm (8.27" x 11.69") */
277 public static final MediaSize ISO_A4 =
278 new MediaSize("ISO_A4", "android", R.string.mediaSize_iso_a4, 8270, 11690);
279 /** ISO A5 media size: 148mm x 210mm (5.83" x 8.27") */
280 public static final MediaSize ISO_A5 =
281 new MediaSize("ISO_A5", "android", R.string.mediaSize_iso_a5, 5830, 8270);
282 /** ISO A6 media size: 105mm x 148mm (4.13" x 5.83") */
283 public static final MediaSize ISO_A6 =
284 new MediaSize("ISO_A6", "android", R.string.mediaSize_iso_a6, 4130, 5830);
285 /** ISO A7 media size: 74mm x 105mm (2.91" x 4.13") */
286 public static final MediaSize ISO_A7 =
287 new MediaSize("ISO_A7", "android", R.string.mediaSize_iso_a7, 2910, 4130);
288 /** ISO A8 media size: 52mm x 74mm (2.05" x 2.91") */
289 public static final MediaSize ISO_A8 =
290 new MediaSize("ISO_A8", "android", R.string.mediaSize_iso_a8, 2050, 2910);
291 /** ISO A9 media size: 37mm x 52mm (1.46" x 2.05") */
292 public static final MediaSize ISO_A9 =
293 new MediaSize("ISO_A9", "android", R.string.mediaSize_iso_a9, 1460, 2050);
294 /** ISO A10 media size: 26mm x 37mm (1.02" x 1.46") */
295 public static final MediaSize ISO_A10 =
296 new MediaSize("ISO_A10", "android", R.string.mediaSize_iso_a10, 1020, 1460);
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700297
Svetoslav773f54d2013-09-03 14:01:43 -0700298 /** ISO B0 media size: 1000mm x 1414mm (39.37" x 55.67") */
299 public static final MediaSize ISO_B0 =
300 new MediaSize("ISO_B0", "android", R.string.mediaSize_iso_b0, 39370, 55670);
301 /** ISO B1 media size: 707mm x 1000mm (27.83" x 39.37") */
302 public static final MediaSize ISO_B1 =
303 new MediaSize("ISO_B1", "android", R.string.mediaSize_iso_b1, 27830, 39370);
304 /** ISO B2 media size: 500mm x 707mm (19.69" x 27.83") */
305 public static final MediaSize ISO_B2 =
306 new MediaSize("ISO_B2", "android", R.string.mediaSize_iso_b2, 19690, 27830);
307 /** ISO B3 media size: 353mm x 500mm (13.90" x 19.69") */
308 public static final MediaSize ISO_B3 =
309 new MediaSize("ISO_B3", "android", R.string.mediaSize_iso_b3, 13900, 19690);
310 /** ISO B4 media size: 250mm x 353mm (9.84" x 13.90") */
311 public static final MediaSize ISO_B4 =
312 new MediaSize("ISO_B4", "android", R.string.mediaSize_iso_b4, 9840, 13900);
313 /** ISO B5 media size: 176mm x 250mm (6.93" x 9.84") */
314 public static final MediaSize ISO_B5 =
315 new MediaSize("ISO_B5", "android", R.string.mediaSize_iso_b5, 6930, 9840);
316 /** ISO B6 media size: 125mm x 176mm (4.92" x 6.93") */
317 public static final MediaSize ISO_B6 =
318 new MediaSize("ISO_B6", "android", R.string.mediaSize_iso_b6, 4920, 6930);
319 /** ISO B7 media size: 88mm x 125mm (3.46" x 4.92") */
320 public static final MediaSize ISO_B7 =
321 new MediaSize("ISO_B7", "android", R.string.mediaSize_iso_b7, 3460, 4920);
322 /** ISO B8 media size: 62mm x 88mm (2.44" x 3.46") */
323 public static final MediaSize ISO_B8 =
324 new MediaSize("ISO_B8", "android", R.string.mediaSize_iso_b8, 2440, 3460);
325 /** ISO B9 media size: 44mm x 62mm (1.73" x 2.44") */
326 public static final MediaSize ISO_B9 =
327 new MediaSize("ISO_B9", "android", R.string.mediaSize_iso_b9, 1730, 2440);
328 /** ISO B10 media size: 31mm x 44mm (1.22" x 1.73") */
329 public static final MediaSize ISO_B10 =
330 new MediaSize("ISO_B10", "android", R.string.mediaSize_iso_b10, 1220, 1730);
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700331
Svetoslav773f54d2013-09-03 14:01:43 -0700332 /** ISO C0 media size: 917mm x 1297mm (36.10" x 51.06") */
333 public static final MediaSize ISO_C0 =
334 new MediaSize("ISO_C0", "android", R.string.mediaSize_iso_c0, 36100, 51060);
335 /** ISO C1 media size: 648mm x 917mm (25.51" x 36.10") */
336 public static final MediaSize ISO_C1 =
337 new MediaSize("ISO_C1", "android", R.string.mediaSize_iso_c1, 25510, 36100);
338 /** ISO C2 media size: 458mm x 648mm (18.03" x 25.51") */
339 public static final MediaSize ISO_C2 =
340 new MediaSize("ISO_C2", "android", R.string.mediaSize_iso_c2, 18030, 25510);
341 /** ISO C3 media size: 324mm x 458mm (12.76" x 18.03") */
342 public static final MediaSize ISO_C3 =
343 new MediaSize("ISO_C3", "android", R.string.mediaSize_iso_c3, 12760, 18030);
344 /** ISO C4 media size: 229mm x 324mm (9.02" x 12.76") */
345 public static final MediaSize ISO_C4 =
346 new MediaSize("ISO_C4", "android", R.string.mediaSize_iso_c4, 9020, 12760);
347 /** ISO C5 media size: 162mm x 229mm (6.38" x 9.02") */
348 public static final MediaSize ISO_C5 =
349 new MediaSize("ISO_C5", "android", R.string.mediaSize_iso_c5, 6380, 9020);
350 /** ISO C6 media size: 114mm x 162mm (4.49" x 6.38") */
351 public static final MediaSize ISO_C6 =
352 new MediaSize("ISO_C6", "android", R.string.mediaSize_iso_c6, 4490, 6380);
353 /** ISO C7 media size: 81mm x 114mm (3.19" x 4.49") */
354 public static final MediaSize ISO_C7 =
355 new MediaSize("ISO_C7", "android", R.string.mediaSize_iso_c7, 3190, 4490);
356 /** ISO C8 media size: 57mm x 81mm (2.24" x 3.19") */
357 public static final MediaSize ISO_C8 =
358 new MediaSize("ISO_C8", "android", R.string.mediaSize_iso_c8, 2240, 3190);
359 /** ISO C9 media size: 40mm x 57mm (1.57" x 2.24") */
360 public static final MediaSize ISO_C9 =
361 new MediaSize("ISO_C9", "android", R.string.mediaSize_iso_c9, 1570, 2240);
362 /** ISO C10 media size: 28mm x 40mm (1.10" x 1.57") */
363 public static final MediaSize ISO_C10 =
364 new MediaSize("ISO_C10", "android", R.string.mediaSize_iso_c10, 1100, 1570);
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700365
366 // North America
367
Svetoslav773f54d2013-09-03 14:01:43 -0700368 /** North America Letter media size: 8.5" x 11" */
369 public static final MediaSize NA_LETTER =
370 new MediaSize("NA_LETTER", "android", R.string.mediaSize_na_letter, 8500, 11000);
371 /** North America Government-Letter media size: 8.0" x 10.5" */
372 public static final MediaSize NA_GOVT_LETTER =
373 new MediaSize("NA_GOVT_LETTER", "android",
374 R.string.mediaSize_na_gvrnmt_letter, 8000, 10500);
375 /** North America Legal media size: 8.5" x 14" */
376 public static final MediaSize NA_LEGAL =
377 new MediaSize("NA_LEGAL", "android", R.string.mediaSize_na_legal, 8500, 14000);
378 /** North America Junior Legal media size: 8.0" x 5.0" */
379 public static final MediaSize NA_JUNIOR_LEGAL =
380 new MediaSize("NA_JUNIOR_LEGAL", "android",
381 R.string.mediaSize_na_junior_legal, 8000, 5000);
382 /** North America Ledger media size: 17" x 11" */
383 public static final MediaSize NA_LEDGER =
384 new MediaSize("NA_LEDGER", "android", R.string.mediaSize_na_ledger, 17000, 11000);
385 /** North America Tabloid media size: 11" x 17" */
386 public static final MediaSize NA_TBLOID =
387 new MediaSize("NA_TABLOID", "android",
388 R.string.mediaSize_na_tabloid, 11000, 17000);
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700389
390 private final String mId;
Svetoslav773f54d2013-09-03 14:01:43 -0700391 /**@hide */
392 public final String mLabel;
393 /**@hide */
394 public final String mPackageName;
395 /**@hide */
396 public final int mLabelResId;
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700397 private final int mWidthMils;
398 private final int mHeightMils;
399
400 /**
Svetoslav773f54d2013-09-03 14:01:43 -0700401 * Creates a new instance. This is the preferred constructor since
402 * it enables the media size label to be shown in a localized fashion
403 * on a locale change.
404 *
405 * @param id The unique media size id.
406 * @param packageName The name of the creating package.
407 * @param labelResId The resource if of a human readable label.
408 * @param widthMils The width in mils (thousands of an inch).
409 * @param heightMils The height in mils (thousands of an inch).
410 *
411 * @throws IllegalArgumentException If the id is empty.
412 * @throws IllegalArgumentException If the label is empty.
413 * @throws IllegalArgumentException If the widthMils is less than or equal to zero.
414 * @throws IllegalArgumentException If the heightMils is less than or equal to zero.
Svetoslava76233a2013-09-05 09:38:02 -0700415 *
416 * @hide
Svetoslav773f54d2013-09-03 14:01:43 -0700417 */
418 public MediaSize(String id, String packageName, int labelResId,
419 int widthMils, int heightMils) {
420 if (TextUtils.isEmpty(id)) {
421 throw new IllegalArgumentException("id cannot be empty.");
422 }
423 if (TextUtils.isEmpty(packageName)) {
424 throw new IllegalArgumentException("packageName cannot be empty.");
425 }
426 if (labelResId <= 0) {
427 throw new IllegalArgumentException("labelResId must be greater than zero.");
428 }
429 if (widthMils <= 0) {
430 throw new IllegalArgumentException("widthMils "
431 + "cannot be less than or equal to zero.");
432 }
433 if (heightMils <= 0) {
434 throw new IllegalArgumentException("heightMils "
435 + "cannot be less than or euqual to zero.");
436 }
437 mPackageName = packageName;
438 mId = id;
439 mLabelResId = labelResId;
440 mWidthMils = widthMils;
441 mHeightMils = heightMils;
442 mLabel = null;
443 }
444
445 /**
Svetoslava76233a2013-09-05 09:38:02 -0700446 * Creates a new instance.
Svetoslav17b7f6e2013-06-24 18:29:33 -0700447 *
448 * @param id The unique media size id.
449 * @param label The <strong>internationalized</strong> human readable label.
450 * @param widthMils The width in mils (thousands of an inch).
451 * @param heightMils The height in mils (thousands of an inch).
452 *
453 * @throws IllegalArgumentException If the id is empty.
454 * @throws IllegalArgumentException If the label is empty.
455 * @throws IllegalArgumentException If the widthMils is less than or equal to zero.
456 * @throws IllegalArgumentException If the heightMils is less than or equal to zero.
457 */
Svetoslav Ganov798bed62013-08-11 12:29:39 -0700458 public MediaSize(String id, String label, int widthMils, int heightMils) {
Svetoslav17b7f6e2013-06-24 18:29:33 -0700459 if (TextUtils.isEmpty(id)) {
460 throw new IllegalArgumentException("id cannot be empty.");
461 }
462 if (TextUtils.isEmpty(label)) {
463 throw new IllegalArgumentException("label cannot be empty.");
464 }
465 if (widthMils <= 0) {
466 throw new IllegalArgumentException("widthMils "
467 + "cannot be less than or equal to zero.");
468 }
469 if (heightMils <= 0) {
470 throw new IllegalArgumentException("heightMils "
471 + "cannot be less than or euqual to zero.");
472 }
473 mId = id;
474 mLabel = label;
475 mWidthMils = widthMils;
476 mHeightMils = heightMils;
Svetoslav773f54d2013-09-03 14:01:43 -0700477 mLabelResId = 0;
478 mPackageName = null;
479 }
480
481 /** @hide */
482 public MediaSize(String id, String label, String packageName,
483 int widthMils, int heightMils, int labelResId) {
484 mPackageName = packageName;
485 mId = id;
486 mLabelResId = labelResId;
487 mWidthMils = widthMils;
488 mHeightMils = heightMils;
489 mLabel = label;
Svetoslav17b7f6e2013-06-24 18:29:33 -0700490 }
491
492 /**
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700493 * Gets the unique media size id.
494 *
495 * @return The unique media size id.
496 */
497 public String getId() {
498 return mId;
499 }
500
501 /**
502 * Gets the human readable media size label.
503 *
Svetoslav773f54d2013-09-03 14:01:43 -0700504 * @param packageManager The package manager for loading the label.
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700505 * @return The human readable label.
506 */
Svetoslav773f54d2013-09-03 14:01:43 -0700507 public String getLabel(PackageManager packageManager) {
508 if (!TextUtils.isEmpty(mPackageName) && mLabelResId > 0) {
509 try {
510 return packageManager.getResourcesForApplication(
511 mPackageName).getString(mLabelResId);
512 } catch (NotFoundException nfe) {
513 Log.w(LOG_TAG, "Could not load resouce" + mLabelResId
514 + " from package " + mPackageName);
515 } catch (NameNotFoundException nnfee) {
516 Log.w(LOG_TAG, "Could not load resouce" + mLabelResId
517 + " from package " + mPackageName);
518 }
519 }
Svetoslav17b7f6e2013-06-24 18:29:33 -0700520 return mLabel;
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700521 }
522
523 /**
524 * Gets the media width in mils (thousands of an inch).
525 *
526 * @return The media width.
527 */
528 public int getWidthMils() {
529 return mWidthMils;
530 }
531
532 /**
533 * Gets the media height in mils (thousands of an inch).
534 *
535 * @return The media height.
536 */
537 public int getHeightMils() {
538 return mHeightMils;
539 }
540
Svetoslav773f54d2013-09-03 14:01:43 -0700541 /**
542 * Gets whether this media size is in portrait which is the
543 * height is greater or equal to the width.
544 *
545 * @return True if the media size is in portrait, false if
546 * it is in landscape.
547 */
548 public boolean isPortrait() {
549 return mHeightMils >= mWidthMils;
550 }
551
552 /**
553 * Returns a new media size in a portrait orientation
Svetoslava76233a2013-09-05 09:38:02 -0700554 * which is the height is the greater dimension.
Svetoslav773f54d2013-09-03 14:01:43 -0700555 *
556 * @return New instance in landscape orientation.
557 */
558 public MediaSize asPortrait() {
Svetoslava36285f2013-09-05 11:27:45 -0700559 return new MediaSize(mId, mLabel, mPackageName,
Svetoslava76233a2013-09-05 09:38:02 -0700560 Math.min(mWidthMils, mHeightMils),
561 Math.max(mWidthMils, mHeightMils),
562 mLabelResId);
Svetoslav773f54d2013-09-03 14:01:43 -0700563 }
564
565 /**
566 * Returns a new media size in a landscape orientation
Svetoslava76233a2013-09-05 09:38:02 -0700567 * which is the height is the lesser dimension.
Svetoslav773f54d2013-09-03 14:01:43 -0700568 *
569 * @return New instance in landscape orientation.
570 */
571 public MediaSize asLandscape() {
Svetoslava36285f2013-09-05 11:27:45 -0700572 return new MediaSize(mId, mLabel, mPackageName,
Svetoslav773f54d2013-09-03 14:01:43 -0700573 Math.max(mWidthMils, mHeightMils),
Svetoslava76233a2013-09-05 09:38:02 -0700574 Math.min(mWidthMils, mHeightMils),
575 mLabelResId);
Svetoslav773f54d2013-09-03 14:01:43 -0700576 }
577
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700578 void writeToParcel(Parcel parcel) {
579 parcel.writeString(mId);
Svetoslav Ganov798bed62013-08-11 12:29:39 -0700580 parcel.writeString(mLabel);
Svetoslav773f54d2013-09-03 14:01:43 -0700581 parcel.writeString(mPackageName);
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700582 parcel.writeInt(mWidthMils);
583 parcel.writeInt(mHeightMils);
Svetoslav773f54d2013-09-03 14:01:43 -0700584 parcel.writeInt(mLabelResId);
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700585 }
586
587 static MediaSize createFromParcel(Parcel parcel) {
588 return new MediaSize(
589 parcel.readString(),
Svetoslav Ganov798bed62013-08-11 12:29:39 -0700590 parcel.readString(),
Svetoslav773f54d2013-09-03 14:01:43 -0700591 parcel.readString(),
592 parcel.readInt(),
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700593 parcel.readInt(),
594 parcel.readInt());
595 }
596
597 @Override
Svetoslav Ganov85b1f882013-07-24 17:00:06 -0700598 public int hashCode() {
599 final int prime = 31;
600 int result = 1;
Svetoslav Ganov85b1f882013-07-24 17:00:06 -0700601 result = prime * result + mWidthMils;
602 result = prime * result + mHeightMils;
603 return result;
604 }
605
606 @Override
607 public boolean equals(Object obj) {
608 if (this == obj) {
609 return true;
610 }
611 if (obj == null) {
612 return false;
613 }
614 if (getClass() != obj.getClass()) {
615 return false;
616 }
617 MediaSize other = (MediaSize) obj;
Svetoslav Ganov85b1f882013-07-24 17:00:06 -0700618 if (mWidthMils != other.mWidthMils) {
619 return false;
620 }
621 if (mHeightMils != other.mHeightMils) {
622 return false;
623 }
624 return true;
625 }
626
627 @Override
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700628 public String toString() {
629 StringBuilder builder = new StringBuilder();
630 builder.append("MediaSize{");
631 builder.append("id: ").append(mId);
Svetoslav17b7f6e2013-06-24 18:29:33 -0700632 builder.append(", label: ").append(mLabel);
Svetoslav773f54d2013-09-03 14:01:43 -0700633 builder.append(", packageName: ").append(mPackageName);
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700634 builder.append(", heightMils: ").append(mHeightMils);
635 builder.append(", widthMils: ").append(mWidthMils);
Svetoslav773f54d2013-09-03 14:01:43 -0700636 builder.append(", labelResId: ").append(mLabelResId);
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700637 builder.append("}");
638 return builder.toString();
639 }
640 }
641
642 /**
643 * This class specifies a supported resolution in dpi (dots per inch).
644 */
645 public static final class Resolution {
Svetoslav773f54d2013-09-03 14:01:43 -0700646 private static final String LOG_TAG = "Resolution";
647
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700648 private final String mId;
Svetoslav773f54d2013-09-03 14:01:43 -0700649 /**@hide */
650 public final String mLabel;
651 /**@hide */
652 public final String mPackageName;
653 /**@hide */
654 public final int mLabelResId;
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700655 private final int mHorizontalDpi;
656 private final int mVerticalDpi;
657
658 /**
Svetoslav773f54d2013-09-03 14:01:43 -0700659 * Creates a new instance. This is the preferred constructor since
660 * it enables the resolution label to be shown in a localized fashion
661 * on a locale change.
662 *
663 * @param id The unique resolution id.
664 * @param packageName The name of the creating package.
665 * @param labelResId The resource id of a human readable label.
666 * @param horizontalDpi The horizontal resolution in dpi.
667 * @param verticalDpi The vertical resolution in dpi.
668 *
669 * @throws IllegalArgumentException If the id is empty.
670 * @throws IllegalArgumentException If the label is empty.
671 * @throws IllegalArgumentException If the horizontalDpi is less than or equal to zero.
672 * @throws IllegalArgumentException If the verticalDpi is less than or equal to zero.
Svetoslava76233a2013-09-05 09:38:02 -0700673 *
674 * @hide
Svetoslav773f54d2013-09-03 14:01:43 -0700675 */
676 public Resolution(String id, String packageName, int labelResId,
677 int horizontalDpi, int verticalDpi) {
678 if (TextUtils.isEmpty(id)) {
679 throw new IllegalArgumentException("id cannot be empty.");
680 }
681 if (TextUtils.isEmpty(packageName)) {
682 throw new IllegalArgumentException("packageName cannot be empty.");
683 }
684 if (labelResId <= 0) {
685 throw new IllegalArgumentException("labelResId must be greater than zero.");
686 }
687 if (horizontalDpi <= 0) {
688 throw new IllegalArgumentException("horizontalDpi "
689 + "cannot be less than or equal to zero.");
690 }
691 if (verticalDpi <= 0) {
692 throw new IllegalArgumentException("verticalDpi"
693 + " cannot be less than or equal to zero.");
694 }
695 mId = id;
696 mPackageName = packageName;
697 mLabelResId = labelResId;
698 mHorizontalDpi = horizontalDpi;
699 mVerticalDpi = verticalDpi;
700 mLabel = null;
701 }
702
703 /**
Svetoslava76233a2013-09-05 09:38:02 -0700704 * Creates a new instance.
Svetoslav17b7f6e2013-06-24 18:29:33 -0700705 *
706 * @param id The unique resolution id.
707 * @param label The <strong>internationalized</strong> human readable label.
708 * @param horizontalDpi The horizontal resolution in dpi.
709 * @param verticalDpi The vertical resolution in dpi.
710 *
711 * @throws IllegalArgumentException If the id is empty.
712 * @throws IllegalArgumentException If the label is empty.
713 * @throws IllegalArgumentException If the horizontalDpi is less than or equal to zero.
714 * @throws IllegalArgumentException If the verticalDpi is less than or equal to zero.
715 */
Svetoslav Ganov798bed62013-08-11 12:29:39 -0700716 public Resolution(String id, String label, int horizontalDpi, int verticalDpi) {
Svetoslav17b7f6e2013-06-24 18:29:33 -0700717 if (TextUtils.isEmpty(id)) {
718 throw new IllegalArgumentException("id cannot be empty.");
719 }
720 if (TextUtils.isEmpty(label)) {
721 throw new IllegalArgumentException("label cannot be empty.");
722 }
723 if (horizontalDpi <= 0) {
724 throw new IllegalArgumentException("horizontalDpi "
725 + "cannot be less than or equal to zero.");
726 }
727 if (verticalDpi <= 0) {
728 throw new IllegalArgumentException("verticalDpi"
729 + " cannot be less than or equal to zero.");
730 }
731 mId = id;
732 mLabel = label;
733 mHorizontalDpi = horizontalDpi;
734 mVerticalDpi = verticalDpi;
Svetoslav773f54d2013-09-03 14:01:43 -0700735 mPackageName = null;
736 mLabelResId = 0;
737 }
738
739 /** @hide */
740 public Resolution(String id, String label, String packageName,
741 int horizontalDpi, int verticalDpi, int labelResId) {
742 mId = id;
743 mPackageName = packageName;
744 mLabelResId = labelResId;
745 mHorizontalDpi = horizontalDpi;
746 mVerticalDpi = verticalDpi;
747 mLabel = label;
Svetoslav17b7f6e2013-06-24 18:29:33 -0700748 }
749
750 /**
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700751 * Gets the unique resolution id.
752 *
753 * @return The unique resolution id.
754 */
755 public String getId() {
756 return mId;
757 }
758
759 /**
760 * Gets the resolution human readable label.
761 *
Svetoslav773f54d2013-09-03 14:01:43 -0700762 * @param packageManager The package manager for loading the label.
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700763 * @return The human readable label.
764 */
Svetoslav773f54d2013-09-03 14:01:43 -0700765 public String getLabel(PackageManager packageManager) {
766 if (!TextUtils.isEmpty(mPackageName) && mLabelResId > 0) {
767 try {
768 return packageManager.getResourcesForApplication(
769 mPackageName).getString(mLabelResId);
770 } catch (NotFoundException nfe) {
771 Log.w(LOG_TAG, "Could not load resouce" + mLabelResId
772 + " from package " + mPackageName);
773 } catch (NameNotFoundException nnfee) {
774 Log.w(LOG_TAG, "Could not load resouce" + mLabelResId
775 + " from package " + mPackageName);
776 }
777 }
Svetoslav17b7f6e2013-06-24 18:29:33 -0700778 return mLabel;
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700779 }
780
781 /**
Svetoslav773f54d2013-09-03 14:01:43 -0700782 * Gets the vertical resolution in dpi.
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700783 *
784 * @return The horizontal resolution.
785 */
786 public int getHorizontalDpi() {
787 return mHorizontalDpi;
788 }
789
790 /**
791 * Gets the vertical resolution in dpi.
792 *
793 * @return The vertical resolution.
794 */
795 public int getVerticalDpi() {
796 return mVerticalDpi;
797 }
798
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700799 void writeToParcel(Parcel parcel) {
800 parcel.writeString(mId);
Svetoslav Ganov798bed62013-08-11 12:29:39 -0700801 parcel.writeString(mLabel);
Svetoslav773f54d2013-09-03 14:01:43 -0700802 parcel.writeString(mPackageName);
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700803 parcel.writeInt(mHorizontalDpi);
804 parcel.writeInt(mVerticalDpi);
Svetoslav773f54d2013-09-03 14:01:43 -0700805 parcel.writeInt(mLabelResId);
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700806 }
807
808 static Resolution createFromParcel(Parcel parcel) {
809 return new Resolution(
810 parcel.readString(),
Svetoslav Ganov798bed62013-08-11 12:29:39 -0700811 parcel.readString(),
Svetoslav773f54d2013-09-03 14:01:43 -0700812 parcel.readString(),
813 parcel.readInt(),
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700814 parcel.readInt(),
815 parcel.readInt());
816 }
817
818 @Override
Svetoslav Ganov85b1f882013-07-24 17:00:06 -0700819 public int hashCode() {
820 final int prime = 31;
821 int result = 1;
Svetoslav Ganov85b1f882013-07-24 17:00:06 -0700822 result = prime * result + mHorizontalDpi;
823 result = prime * result + mVerticalDpi;
824 return result;
825 }
826
827 @Override
828 public boolean equals(Object obj) {
829 if (this == obj) {
830 return true;
831 }
832 if (obj == null) {
833 return false;
834 }
835 if (getClass() != obj.getClass()) {
836 return false;
837 }
838 Resolution other = (Resolution) obj;
Svetoslav Ganov85b1f882013-07-24 17:00:06 -0700839 if (mHorizontalDpi != other.mHorizontalDpi) {
840 return false;
841 }
842 if (mVerticalDpi != other.mVerticalDpi) {
843 return false;
844 }
845 return true;
846 }
847
848 @Override
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700849 public String toString() {
850 StringBuilder builder = new StringBuilder();
851 builder.append("Resolution{");
852 builder.append("id: ").append(mId);
Svetoslav17b7f6e2013-06-24 18:29:33 -0700853 builder.append(", label: ").append(mLabel);
Svetoslav773f54d2013-09-03 14:01:43 -0700854 builder.append(", packageName: ").append(mPackageName);
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700855 builder.append(", horizontalDpi: ").append(mHorizontalDpi);
856 builder.append(", verticalDpi: ").append(mVerticalDpi);
Svetoslav773f54d2013-09-03 14:01:43 -0700857 builder.append(", labelResId: ").append(mLabelResId);
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700858 builder.append("}");
859 return builder.toString();
860 }
861 }
862
863 /**
864 * This class specifies content margins.
865 */
866 public static final class Margins {
Svetoslav Ganovaec14172013-08-27 00:30:54 -0700867 public static final Margins NO_MARGINS = new Margins(0, 0, 0, 0);
868
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700869 private final int mLeftMils;
870 private final int mTopMils;
871 private final int mRightMils;
872 private final int mBottomMils;
873
874 /**
Svetoslav17b7f6e2013-06-24 18:29:33 -0700875 * Creates a new instance.
876 *
877 * @param leftMils The left margin in mils (thousands of an inch).
878 * @param topMils The top margin in mils (thousands of an inch).
879 * @param rightMils The right margin in mils (thousands of an inch).
880 * @param bottomMils The bottom margin in mils (thousands of an inch).
Svetoslav17b7f6e2013-06-24 18:29:33 -0700881 */
882 public Margins(int leftMils, int topMils, int rightMils, int bottomMils) {
Svetoslav Ganovaec14172013-08-27 00:30:54 -0700883 if (leftMils > rightMils) {
884 throw new IllegalArgumentException("leftMils cannot be less than rightMils.");
Svetoslav17b7f6e2013-06-24 18:29:33 -0700885 }
Svetoslav Ganovaec14172013-08-27 00:30:54 -0700886 if (topMils > bottomMils) {
887 throw new IllegalArgumentException("topMils cannot be less than bottomMils.");
Svetoslav17b7f6e2013-06-24 18:29:33 -0700888 }
889 mTopMils = topMils;
890 mLeftMils = leftMils;
891 mRightMils = rightMils;
892 mBottomMils = bottomMils;
893 }
894
895 /**
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700896 * Gets the left margin in mils (thousands of an inch).
897 *
898 * @return The left margin.
899 */
900 public int getLeftMils() {
901 return mLeftMils;
902 }
903
904 /**
905 * Gets the top margin in mils (thousands of an inch).
906 *
907 * @return The top margin.
908 */
909 public int getTopMils() {
910 return mTopMils;
911 }
912
913 /**
914 * Gets the right margin in mils (thousands of an inch).
915 *
916 * @return The right margin.
917 */
918 public int getRightMils() {
919 return mRightMils;
920 }
921
922 /**
923 * Gets the bottom margin in mils (thousands of an inch).
924 *
925 * @return The bottom margin.
926 */
927 public int getBottomMils() {
928 return mBottomMils;
929 }
930
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700931 void writeToParcel(Parcel parcel) {
932 parcel.writeInt(mLeftMils);
933 parcel.writeInt(mTopMils);
934 parcel.writeInt(mRightMils);
935 parcel.writeInt(mBottomMils);
936 }
937
938 static Margins createFromParcel(Parcel parcel) {
939 return new Margins(
940 parcel.readInt(),
941 parcel.readInt(),
942 parcel.readInt(),
943 parcel.readInt());
944 }
945
946 @Override
Svetoslav Ganov85b1f882013-07-24 17:00:06 -0700947 public int hashCode() {
948 final int prime = 31;
949 int result = 1;
950 result = prime * result + mBottomMils;
951 result = prime * result + mLeftMils;
952 result = prime * result + mRightMils;
953 result = prime * result + mTopMils;
954 return result;
955 }
956
957 @Override
958 public boolean equals(Object obj) {
959 if (this == obj) {
960 return true;
961 }
962 if (obj == null) {
963 return false;
964 }
965 if (getClass() != obj.getClass()) {
966 return false;
967 }
968 Margins other = (Margins) obj;
969 if (mBottomMils != other.mBottomMils) {
970 return false;
971 }
972 if (mLeftMils != other.mLeftMils) {
973 return false;
974 }
975 if (mRightMils != other.mRightMils) {
976 return false;
977 }
978 if (mTopMils != other.mTopMils) {
979 return false;
980 }
981 return true;
982 }
983
984 @Override
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700985 public String toString() {
986 StringBuilder builder = new StringBuilder();
987 builder.append("Margins{");
988 builder.append("leftMils: ").append(mLeftMils);
989 builder.append(", topMils: ").append(mTopMils);
990 builder.append(", rightMils: ").append(mRightMils);
991 builder.append(", bottomMils: ").append(mBottomMils);
992 builder.append("}");
993 return builder.toString();
994 }
995 }
996
Svetoslav Ganov798bed62013-08-11 12:29:39 -0700997 static String colorModeToString(int colorMode) {
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700998 switch (colorMode) {
999 case COLOR_MODE_MONOCHROME: {
1000 return "COLOR_MODE_MONOCHROME";
1001 }
1002 case COLOR_MODE_COLOR: {
1003 return "COLOR_MODE_COLOR";
1004 }
1005 default:
1006 return "COLOR_MODE_UNKNOWN";
1007 }
1008 }
1009
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -07001010 static void enforceValidColorMode(int colorMode) {
Svetoslav Ganovaec14172013-08-27 00:30:54 -07001011 if ((colorMode & VALID_COLOR_MODES) == 0 && Integer.bitCount(colorMode) == 1) {
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -07001012 throw new IllegalArgumentException("invalid color mode: " + colorMode);
1013 }
1014 }
1015
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -07001016 /**
1017 * Builder for creating {@link PrintAttributes}.
1018 */
1019 public static final class Builder {
1020 private final PrintAttributes mAttributes = new PrintAttributes();
1021
1022 /**
1023 * Sets the media size.
1024 *
1025 * @param mediaSize The media size.
1026 * @return This builder.
1027 */
1028 public Builder setMediaSize(MediaSize mediaSize) {
1029 mAttributes.setMediaSize(mediaSize);
1030 return this;
1031 }
1032
1033 /**
1034 * Sets the resolution.
1035 *
1036 * @param resolution The resolution.
1037 * @return This builder.
1038 */
1039 public Builder setResolution(Resolution resolution) {
1040 mAttributes.setResolution(resolution);
1041 return this;
1042 }
1043
1044 /**
1045 * Sets the margins.
1046 *
1047 * @param margins The margins.
1048 * @return This builder.
1049 */
1050 public Builder setMargins(Margins margins) {
1051 mAttributes.setMargins(margins);
1052 return this;
1053 }
1054
1055 /**
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -07001056 * Sets the color mode.
1057 *
1058 * @param colorMode A valid color mode or zero.
1059 * @return This builder.
1060 *
1061 * @see PrintAttributes#COLOR_MODE_MONOCHROME
1062 * @see PrintAttributes#COLOR_MODE_COLOR
1063 */
1064 public Builder setColorMode(int colorMode) {
1065 if (Integer.bitCount(colorMode) > 1) {
1066 throw new IllegalArgumentException("can specify at most one colorMode bit.");
1067 }
1068 mAttributes.setColorMode(colorMode);
1069 return this;
1070 }
1071
1072 /**
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -07001073 * Creates a new {@link PrintAttributes} instance.
1074 *
1075 * @return The new instance.
1076 */
1077 public PrintAttributes create() {
1078 return mAttributes;
1079 }
1080 }
1081
1082 public static final Parcelable.Creator<PrintAttributes> CREATOR =
1083 new Creator<PrintAttributes>() {
1084 @Override
1085 public PrintAttributes createFromParcel(Parcel parcel) {
1086 return new PrintAttributes(parcel);
1087 }
1088
1089 @Override
1090 public PrintAttributes[] newArray(int size) {
1091 return new PrintAttributes[size];
1092 }
1093 };
1094}