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