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 17 package android.print; 18 19 import android.annotation.FloatRange; 20 import android.annotation.IntDef; 21 import android.annotation.IntRange; 22 import android.annotation.NonNull; 23 import android.annotation.Nullable; 24 import android.annotation.StringRes; 25 import android.annotation.TestApi; 26 import android.content.pm.PackageManager; 27 import android.content.res.Resources; 28 import android.os.Bundle; 29 import android.os.Parcel; 30 import android.os.Parcelable; 31 32 import com.android.internal.util.Preconditions; 33 34 import java.lang.annotation.Retention; 35 import java.lang.annotation.RetentionPolicy; 36 import java.util.Arrays; 37 38 /** 39 * This class represents the description of a print job. The print job 40 * state includes properties such as its id, print attributes used for 41 * generating the content, and so on. Note that the print jobs state may 42 * change over time and this class represents a snapshot of this state. 43 */ 44 public final class PrintJobInfo implements Parcelable { 45 46 /** @hide */ 47 @IntDef({ 48 STATE_CREATED, STATE_QUEUED, STATE_STARTED, STATE_BLOCKED, STATE_COMPLETED, 49 STATE_FAILED, STATE_CANCELED 50 }) 51 @Retention(RetentionPolicy.SOURCE) 52 public @interface State { 53 } 54 55 /** 56 * Constant for matching any print job state. 57 * 58 * @hide 59 */ 60 public static final int STATE_ANY = -1; 61 62 /** 63 * Constant for matching any print job state. 64 * 65 * @hide 66 */ 67 public static final int STATE_ANY_VISIBLE_TO_CLIENTS = -2; 68 69 /** 70 * Constant for matching any active print job state. 71 * 72 * @hide 73 */ 74 public static final int STATE_ANY_ACTIVE = -3; 75 76 /** 77 * Constant for matching any scheduled, i.e. delivered to a print 78 * service, print job state. 79 * 80 * @hide 81 */ 82 public static final int STATE_ANY_SCHEDULED = -4; 83 84 /** 85 * Print job state: The print job is being created but not yet 86 * ready to be printed. 87 * <p> 88 * Next valid states: {@link #STATE_QUEUED} 89 * </p> 90 */ 91 public static final int STATE_CREATED = 1; 92 93 /** 94 * Print job state: The print jobs is created, it is ready 95 * to be printed and should be processed. 96 * <p> 97 * Next valid states: {@link #STATE_STARTED}, {@link #STATE_FAILED}, 98 * {@link #STATE_CANCELED} 99 * </p> 100 */ 101 public static final int STATE_QUEUED = 2; 102 103 /** 104 * Print job state: The print job is being printed. 105 * <p> 106 * Next valid states: {@link #STATE_COMPLETED}, {@link #STATE_FAILED}, 107 * {@link #STATE_CANCELED}, {@link #STATE_BLOCKED} 108 * </p> 109 */ 110 public static final int STATE_STARTED = 3; 111 112 /** 113 * Print job state: The print job is blocked. 114 * <p> 115 * Next valid states: {@link #STATE_FAILED}, {@link #STATE_CANCELED}, 116 * {@link #STATE_STARTED} 117 * </p> 118 */ 119 public static final int STATE_BLOCKED = 4; 120 121 /** 122 * Print job state: The print job is successfully printed. 123 * This is a terminal state. 124 * <p> 125 * Next valid states: None 126 * </p> 127 */ 128 public static final int STATE_COMPLETED = 5; 129 130 /** 131 * Print job state: The print job was printing but printing failed. 132 * <p> 133 * Next valid states: {@link #STATE_CANCELED}, {@link #STATE_STARTED} 134 * </p> 135 */ 136 public static final int STATE_FAILED = 6; 137 138 /** 139 * Print job state: The print job is canceled. 140 * This is a terminal state. 141 * <p> 142 * Next valid states: None 143 * </p> 144 */ 145 public static final int STATE_CANCELED = 7; 146 147 /** The unique print job id. */ 148 private PrintJobId mId; 149 150 /** The human readable print job label. */ 151 private String mLabel; 152 153 /** The unique id of the printer. */ 154 private PrinterId mPrinterId; 155 156 /** The name of the printer - internally used */ 157 private String mPrinterName; 158 159 /** The state of the print job. */ 160 private int mState; 161 162 /** The id of the app that created the job. */ 163 private int mAppId; 164 165 /** Optional tag assigned by a print service.*/ 166 private String mTag; 167 168 /** The wall time when the print job was created. */ 169 private long mCreationTime; 170 171 /** How many copies to print. */ 172 private int mCopies; 173 174 /** The pages to print */ 175 private PageRange[] mPageRanges; 176 177 /** The print job attributes size. */ 178 private PrintAttributes mAttributes; 179 180 /** Information about the printed document. */ 181 private PrintDocumentInfo mDocumentInfo; 182 183 /** The progress made on printing this job or -1 if not set. */ 184 private float mProgress; 185 186 /** A short string describing the status of this job. */ 187 private @Nullable CharSequence mStatus; 188 189 /** A string resource describing the status of this job. */ 190 private @StringRes int mStatusRes; 191 private @Nullable CharSequence mStatusResAppPackageName; 192 193 /** Advanced printer specific options. */ 194 private Bundle mAdvancedOptions; 195 196 /** Whether we are trying to cancel this print job. */ 197 private boolean mCanceling; 198 199 /** @hide*/ PrintJobInfo()200 public PrintJobInfo() { 201 mProgress = -1; 202 } 203 204 /** @hide */ PrintJobInfo(PrintJobInfo other)205 public PrintJobInfo(PrintJobInfo other) { 206 mId = other.mId; 207 mLabel = other.mLabel; 208 mPrinterId = other.mPrinterId; 209 mPrinterName = other.mPrinterName; 210 mState = other.mState; 211 mAppId = other.mAppId; 212 mTag = other.mTag; 213 mCreationTime = other.mCreationTime; 214 mCopies = other.mCopies; 215 mPageRanges = other.mPageRanges; 216 mAttributes = other.mAttributes; 217 mDocumentInfo = other.mDocumentInfo; 218 mProgress = other.mProgress; 219 mStatus = other.mStatus; 220 mStatusRes = other.mStatusRes; 221 mStatusResAppPackageName = other.mStatusResAppPackageName; 222 mCanceling = other.mCanceling; 223 mAdvancedOptions = other.mAdvancedOptions; 224 } 225 PrintJobInfo(@onNull Parcel parcel)226 private PrintJobInfo(@NonNull Parcel parcel) { 227 mId = parcel.readParcelable(null); 228 mLabel = parcel.readString(); 229 mPrinterId = parcel.readParcelable(null); 230 mPrinterName = parcel.readString(); 231 mState = parcel.readInt(); 232 mAppId = parcel.readInt(); 233 mTag = parcel.readString(); 234 mCreationTime = parcel.readLong(); 235 mCopies = parcel.readInt(); 236 Parcelable[] parcelables = parcel.readParcelableArray(null); 237 if (parcelables != null) { 238 mPageRanges = new PageRange[parcelables.length]; 239 for (int i = 0; i < parcelables.length; i++) { 240 mPageRanges[i] = (PageRange) parcelables[i]; 241 } 242 } 243 mAttributes = (PrintAttributes) parcel.readParcelable(null); 244 mDocumentInfo = (PrintDocumentInfo) parcel.readParcelable(null); 245 mProgress = parcel.readFloat(); 246 mStatus = parcel.readCharSequence(); 247 mStatusRes = parcel.readInt(); 248 mStatusResAppPackageName = parcel.readCharSequence(); 249 mCanceling = (parcel.readInt() == 1); 250 mAdvancedOptions = parcel.readBundle(); 251 252 if (mAdvancedOptions != null) { 253 Preconditions.checkArgument(!mAdvancedOptions.containsKey(null)); 254 } 255 } 256 257 /** 258 * Gets the unique print job id. 259 * 260 * @return The id. 261 */ getId()262 public @Nullable PrintJobId getId() { 263 return mId; 264 } 265 266 /** 267 * Sets the unique print job id. 268 * 269 * @param id The job id. 270 * 271 * @hide 272 */ setId(@onNull PrintJobId id)273 public void setId(@NonNull PrintJobId id) { 274 this.mId = id; 275 } 276 277 /** 278 * Gets the human readable job label. 279 * 280 * @return The label. 281 */ getLabel()282 public @NonNull String getLabel() { 283 return mLabel; 284 } 285 286 /** 287 * Sets the human readable job label. 288 * 289 * @param label The label. 290 * 291 * @hide 292 */ setLabel(@onNull String label)293 public void setLabel(@NonNull String label) { 294 mLabel = label; 295 } 296 297 /** 298 * Gets the unique target printer id. 299 * 300 * @return The target printer id. 301 */ getPrinterId()302 public @Nullable PrinterId getPrinterId() { 303 return mPrinterId; 304 } 305 306 /** 307 * Sets the unique target printer id. 308 * 309 * @param printerId The target printer id. 310 * 311 * @hide 312 */ setPrinterId(@onNull PrinterId printerId)313 public void setPrinterId(@NonNull PrinterId printerId) { 314 mPrinterId = printerId; 315 } 316 317 /** 318 * Gets the name of the target printer. 319 * 320 * @return The printer name. 321 * 322 * @hide 323 */ getPrinterName()324 public @Nullable String getPrinterName() { 325 return mPrinterName; 326 } 327 328 /** 329 * Sets the name of the target printer. 330 * 331 * @param printerName The printer name. 332 * 333 * @hide 334 */ setPrinterName(@onNull String printerName)335 public void setPrinterName(@NonNull String printerName) { 336 mPrinterName = printerName; 337 } 338 339 /** 340 * Gets the current job state. 341 * 342 * @return The job state. 343 * 344 * @see #STATE_CREATED 345 * @see #STATE_QUEUED 346 * @see #STATE_STARTED 347 * @see #STATE_COMPLETED 348 * @see #STATE_BLOCKED 349 * @see #STATE_FAILED 350 * @see #STATE_CANCELED 351 */ getState()352 public @State int getState() { 353 return mState; 354 } 355 356 /** 357 * Sets the current job state. 358 * 359 * @param state The job state. 360 * 361 * @hide 362 */ setState(int state)363 public void setState(int state) { 364 mState = state; 365 } 366 367 /** 368 * Sets the progress of the print job. 369 * 370 * @param progress the progress of the job 371 * 372 * @hide 373 */ setProgress(@loatRangefrom=0.0, to=1.0) float progress)374 public void setProgress(@FloatRange(from=0.0, to=1.0) float progress) { 375 Preconditions.checkArgumentInRange(progress, 0, 1, "progress"); 376 377 mProgress = progress; 378 } 379 380 /** 381 * Sets the status of the print job. 382 * 383 * @param status the status of the job, can be null 384 * 385 * @hide 386 */ setStatus(@ullable CharSequence status)387 public void setStatus(@Nullable CharSequence status) { 388 mStatusRes = 0; 389 mStatusResAppPackageName = null; 390 391 mStatus = status; 392 } 393 394 /** 395 * Sets the status of the print job. 396 * 397 * @param status The new status as a string resource 398 * @param appPackageName App package name the resource belongs to 399 * 400 * @hide 401 */ setStatus(@tringRes int status, @NonNull CharSequence appPackageName)402 public void setStatus(@StringRes int status, @NonNull CharSequence appPackageName) { 403 mStatus = null; 404 405 mStatusRes = status; 406 mStatusResAppPackageName = appPackageName; 407 } 408 409 /** 410 * Sets the owning application id. 411 * 412 * @return The owning app id. 413 * 414 * @hide 415 */ getAppId()416 public int getAppId() { 417 return mAppId; 418 } 419 420 /** 421 * Sets the owning application id. 422 * 423 * @param appId The owning app id. 424 * 425 * @hide 426 */ setAppId(int appId)427 public void setAppId(int appId) { 428 mAppId = appId; 429 } 430 431 /** 432 * Gets the optional tag assigned by a print service. 433 * 434 * @return The tag. 435 * 436 * @hide 437 */ getTag()438 public String getTag() { 439 return mTag; 440 } 441 442 /** 443 * Sets the optional tag assigned by a print service. 444 * 445 * @param tag The tag. 446 * 447 * @hide 448 */ setTag(String tag)449 public void setTag(String tag) { 450 mTag = tag; 451 } 452 453 /** 454 * Gets the wall time in millisecond when this print job was created. 455 * 456 * @return The creation time in milliseconds. 457 */ getCreationTime()458 public long getCreationTime() { 459 return mCreationTime; 460 } 461 462 /** 463 * Sets the wall time in milliseconds when this print job was created. 464 * 465 * @param creationTime The creation time in milliseconds. 466 * 467 * @hide 468 */ setCreationTime(long creationTime)469 public void setCreationTime(long creationTime) { 470 if (creationTime < 0) { 471 throw new IllegalArgumentException("creationTime must be non-negative."); 472 } 473 mCreationTime = creationTime; 474 } 475 476 /** 477 * Gets the number of copies. 478 * 479 * @return The number of copies or zero if not set. 480 */ getCopies()481 public @IntRange(from = 0) int getCopies() { 482 return mCopies; 483 } 484 485 /** 486 * Sets the number of copies. 487 * 488 * @param copyCount The number of copies. 489 * 490 * @hide 491 */ setCopies(int copyCount)492 public void setCopies(int copyCount) { 493 if (copyCount < 1) { 494 throw new IllegalArgumentException("Copies must be more than one."); 495 } 496 mCopies = copyCount; 497 } 498 499 /** 500 * Gets the included pages. 501 * 502 * @return The included pages or <code>null</code> if not set. 503 */ getPages()504 public @Nullable PageRange[] getPages() { 505 return mPageRanges; 506 } 507 508 /** 509 * Sets the included pages. 510 * 511 * @param pageRanges The included pages. 512 * 513 * @hide 514 */ setPages(PageRange[] pageRanges)515 public void setPages(PageRange[] pageRanges) { 516 mPageRanges = pageRanges; 517 } 518 519 /** 520 * Gets the print job attributes. 521 * 522 * @return The attributes. 523 */ getAttributes()524 public @NonNull PrintAttributes getAttributes() { 525 return mAttributes; 526 } 527 528 /** 529 * Sets the print job attributes. 530 * 531 * @param attributes The attributes. 532 * 533 * @hide 534 */ setAttributes(PrintAttributes attributes)535 public void setAttributes(PrintAttributes attributes) { 536 mAttributes = attributes; 537 } 538 539 /** 540 * Gets the info describing the printed document. 541 * 542 * @return The document info. 543 * 544 * @hide 545 */ getDocumentInfo()546 public PrintDocumentInfo getDocumentInfo() { 547 return mDocumentInfo; 548 } 549 550 /** 551 * Sets the info describing the printed document. 552 * 553 * @param info The document info. 554 * 555 * @hide 556 */ setDocumentInfo(PrintDocumentInfo info)557 public void setDocumentInfo(PrintDocumentInfo info) { 558 mDocumentInfo = info; 559 } 560 561 /** 562 * Gets whether this print is being cancelled. 563 * 564 * @return True if the print job is being cancelled. 565 * 566 * @hide 567 */ isCancelling()568 public boolean isCancelling() { 569 return mCanceling; 570 } 571 572 /** 573 * Sets whether this print is being cancelled. 574 * 575 * @param cancelling True if the print job is being cancelled. 576 * 577 * @hide 578 */ setCancelling(boolean cancelling)579 public void setCancelling(boolean cancelling) { 580 mCanceling = cancelling; 581 } 582 583 /** 584 * Gets whether this job has a given advanced (printer specific) print 585 * option. 586 * 587 * @param key The option key. 588 * @return Whether the option is present. 589 */ hasAdvancedOption(String key)590 public boolean hasAdvancedOption(String key) { 591 return mAdvancedOptions != null && mAdvancedOptions.containsKey(key); 592 } 593 594 /** 595 * Gets the value of an advanced (printer specific) print option. 596 * 597 * @param key The option key. 598 * @return The option value. 599 */ getAdvancedStringOption(String key)600 public String getAdvancedStringOption(String key) { 601 if (mAdvancedOptions != null) { 602 return mAdvancedOptions.getString(key); 603 } 604 return null; 605 } 606 607 /** 608 * Gets the value of an advanced (printer specific) print option. 609 * 610 * @param key The option key. 611 * @return The option value. 612 */ getAdvancedIntOption(String key)613 public int getAdvancedIntOption(String key) { 614 if (mAdvancedOptions != null) { 615 return mAdvancedOptions.getInt(key); 616 } 617 return 0; 618 } 619 620 /** 621 * Gets the advanced options. 622 * 623 * @return The advanced options. 624 * 625 * @hide 626 */ getAdvancedOptions()627 public Bundle getAdvancedOptions() { 628 return mAdvancedOptions; 629 } 630 631 /** 632 * Sets the advanced options. 633 * 634 * @param options The advanced options. 635 * 636 * @hide 637 */ setAdvancedOptions(Bundle options)638 public void setAdvancedOptions(Bundle options) { 639 mAdvancedOptions = options; 640 } 641 642 @Override describeContents()643 public int describeContents() { 644 return 0; 645 } 646 647 @Override writeToParcel(Parcel parcel, int flags)648 public void writeToParcel(Parcel parcel, int flags) { 649 parcel.writeParcelable(mId, flags); 650 parcel.writeString(mLabel); 651 parcel.writeParcelable(mPrinterId, flags); 652 parcel.writeString(mPrinterName); 653 parcel.writeInt(mState); 654 parcel.writeInt(mAppId); 655 parcel.writeString(mTag); 656 parcel.writeLong(mCreationTime); 657 parcel.writeInt(mCopies); 658 parcel.writeParcelableArray(mPageRanges, flags); 659 parcel.writeParcelable(mAttributes, flags); 660 parcel.writeParcelable(mDocumentInfo, 0); 661 parcel.writeFloat(mProgress); 662 parcel.writeCharSequence(mStatus); 663 parcel.writeInt(mStatusRes); 664 parcel.writeCharSequence(mStatusResAppPackageName); 665 parcel.writeInt(mCanceling ? 1 : 0); 666 parcel.writeBundle(mAdvancedOptions); 667 } 668 669 @Override toString()670 public String toString() { 671 StringBuilder builder = new StringBuilder(); 672 builder.append("PrintJobInfo{"); 673 builder.append("label: ").append(mLabel); 674 builder.append(", id: ").append(mId); 675 builder.append(", state: ").append(stateToString(mState)); 676 builder.append(", printer: " + mPrinterId); 677 builder.append(", tag: ").append(mTag); 678 builder.append(", creationTime: " + mCreationTime); 679 builder.append(", copies: ").append(mCopies); 680 builder.append(", attributes: " + (mAttributes != null 681 ? mAttributes.toString() : null)); 682 builder.append(", documentInfo: " + (mDocumentInfo != null 683 ? mDocumentInfo.toString() : null)); 684 builder.append(", cancelling: " + mCanceling); 685 builder.append(", pages: " + (mPageRanges != null 686 ? Arrays.toString(mPageRanges) : null)); 687 builder.append(", hasAdvancedOptions: " + (mAdvancedOptions != null)); 688 builder.append(", progress: " + mProgress); 689 builder.append(", status: " + (mStatus != null 690 ? mStatus.toString() : null)); 691 builder.append(", statusRes: " + mStatusRes); 692 builder.append(", statusResAppPackageName: " + (mStatusResAppPackageName != null 693 ? mStatusResAppPackageName.toString() : null)); 694 builder.append("}"); 695 return builder.toString(); 696 } 697 698 /** @hide */ stateToString(int state)699 public static String stateToString(int state) { 700 switch (state) { 701 case STATE_CREATED: { 702 return "STATE_CREATED"; 703 } 704 case STATE_QUEUED: { 705 return "STATE_QUEUED"; 706 } 707 case STATE_STARTED: { 708 return "STATE_STARTED"; 709 } 710 case STATE_BLOCKED: { 711 return "STATE_BLOCKED"; 712 } 713 case STATE_FAILED: { 714 return "STATE_FAILED"; 715 } 716 case STATE_COMPLETED: { 717 return "STATE_COMPLETED"; 718 } 719 case STATE_CANCELED: { 720 return "STATE_CANCELED"; 721 } 722 default: { 723 return "STATE_UNKNOWN"; 724 } 725 } 726 } 727 728 /** 729 * Get the progress that has been made printing this job. 730 * 731 * @return the print progress or -1 if not set 732 * @hide 733 */ 734 @TestApi getProgress()735 public float getProgress() { 736 return mProgress; 737 } 738 739 /** 740 * Get the status of this job. 741 * 742 * @param pm Package manager used to resolve the string 743 * 744 * @return the status of this job or null if not set 745 * @hide 746 */ 747 @TestApi getStatus(@onNull PackageManager pm)748 public @Nullable CharSequence getStatus(@NonNull PackageManager pm) { 749 if (mStatusRes == 0) { 750 return mStatus; 751 } else { 752 try { 753 return pm.getResourcesForApplication(mStatusResAppPackageName.toString()) 754 .getString(mStatusRes); 755 } catch (PackageManager.NameNotFoundException | Resources.NotFoundException e) { 756 return null; 757 } 758 } 759 } 760 761 /** 762 * Builder for creating a {@link PrintJobInfo}. 763 */ 764 public static final class Builder { 765 private final PrintJobInfo mPrototype; 766 767 /** 768 * Constructor. 769 * 770 * @param prototype Prototype to use as a starting point. 771 * Can be <code>null</code>. 772 */ Builder(@ullable PrintJobInfo prototype)773 public Builder(@Nullable PrintJobInfo prototype) { 774 mPrototype = (prototype != null) 775 ? new PrintJobInfo(prototype) 776 : new PrintJobInfo(); 777 } 778 779 /** 780 * Sets the number of copies. 781 * 782 * @param copies The number of copies. 783 */ setCopies(@ntRangefrom = 1) int copies)784 public void setCopies(@IntRange(from = 1) int copies) { 785 mPrototype.mCopies = copies; 786 } 787 788 /** 789 * Sets the print job attributes. 790 * 791 * @param attributes The attributes. 792 */ setAttributes(@onNull PrintAttributes attributes)793 public void setAttributes(@NonNull PrintAttributes attributes) { 794 mPrototype.mAttributes = attributes; 795 } 796 797 /** 798 * Sets the included pages. 799 * 800 * @param pages The included pages. 801 */ setPages(@onNull PageRange[] pages)802 public void setPages(@NonNull PageRange[] pages) { 803 mPrototype.mPageRanges = pages; 804 } 805 806 /** 807 * Sets the progress of the print job. 808 * 809 * @param progress the progress of the job 810 * @hide 811 */ setProgress(@loatRangefrom=0.0, to=1.0) float progress)812 public void setProgress(@FloatRange(from=0.0, to=1.0) float progress) { 813 Preconditions.checkArgumentInRange(progress, 0, 1, "progress"); 814 815 mPrototype.mProgress = progress; 816 } 817 818 /** 819 * Sets the status of the print job. 820 * 821 * @param status the status of the job, can be null 822 * @hide 823 */ setStatus(@ullable CharSequence status)824 public void setStatus(@Nullable CharSequence status) { 825 mPrototype.mStatus = status; 826 } 827 828 /** 829 * Puts an advanced (printer specific) option. 830 * 831 * @param key The option key. 832 * @param value The option value. 833 */ putAdvancedOption(@onNull String key, @Nullable String value)834 public void putAdvancedOption(@NonNull String key, @Nullable String value) { 835 Preconditions.checkNotNull(key, "key cannot be null"); 836 837 if (mPrototype.mAdvancedOptions == null) { 838 mPrototype.mAdvancedOptions = new Bundle(); 839 } 840 mPrototype.mAdvancedOptions.putString(key, value); 841 } 842 843 /** 844 * Puts an advanced (printer specific) option. 845 * 846 * @param key The option key. 847 * @param value The option value. 848 */ putAdvancedOption(@onNull String key, int value)849 public void putAdvancedOption(@NonNull String key, int value) { 850 if (mPrototype.mAdvancedOptions == null) { 851 mPrototype.mAdvancedOptions = new Bundle(); 852 } 853 mPrototype.mAdvancedOptions.putInt(key, value); 854 } 855 856 /** 857 * Creates a new {@link PrintJobInfo} instance. 858 * 859 * @return The new instance. 860 */ build()861 public @NonNull PrintJobInfo build() { 862 return mPrototype; 863 } 864 } 865 866 public static final Parcelable.Creator<PrintJobInfo> CREATOR = 867 new Creator<PrintJobInfo>() { 868 @Override 869 public PrintJobInfo createFromParcel(Parcel parcel) { 870 return new PrintJobInfo(parcel); 871 } 872 873 @Override 874 public PrintJobInfo[] newArray(int size) { 875 return new PrintJobInfo[size]; 876 } 877 }; 878 } 879