PrintJob.java revision 798bed6cc7d273e72b0253288605db9cd2b57740
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.printservice; 18 19import android.os.RemoteException; 20import android.print.PrintJobInfo; 21import android.util.Log; 22 23/** 24 * This class represents a print job from the perspective of a print 25 * service. It provides APIs for observing the print job state and 26 * performing operations on the print job. 27 */ 28public final class PrintJob { 29 30 private static final String LOG_TAG = "PrintJob"; 31 32 private final IPrintServiceClient mPrintServiceClient; 33 34 private final PrintDocument mDocument; 35 36 private PrintJobInfo mCachedInfo; 37 38 PrintJob(PrintJobInfo jobInfo, IPrintServiceClient client) { 39 mCachedInfo = jobInfo; 40 mPrintServiceClient = client; 41 mDocument = new PrintDocument(mCachedInfo.getId(), client, 42 jobInfo.getDocumentInfo()); 43 } 44 45 /** 46 * Gets the unique print job id. 47 * 48 * @return The id. 49 */ 50 public int getId() { 51 return mCachedInfo.getId(); 52 } 53 54 /** 55 * Gets the {@link PrintJobInfo} that describes this job. 56 * <p> 57 * <strong>Node:</strong>The returned info object is a snapshot of the 58 * current print job state. Every call to this method returns a fresh 59 * info object that reflects the current print job state. 60 * </p> 61 * 62 * @return The print job info. 63 */ 64 public PrintJobInfo getInfo() { 65 if (isInImmutableState()) { 66 return mCachedInfo; 67 } 68 PrintJobInfo info = null; 69 try { 70 info = mPrintServiceClient.getPrintJobInfo(mCachedInfo.getId()); 71 } catch (RemoteException re) { 72 Log.e(LOG_TAG, "Couldn't get info for job: " + mCachedInfo.getId(), re); 73 } 74 if (info != null) { 75 mCachedInfo = info; 76 } 77 return mCachedInfo; 78 } 79 80 /** 81 * Gets the printed document. 82 * 83 * @return The document. 84 */ 85 public PrintDocument getDocument() { 86 return mDocument; 87 } 88 89 /** 90 * Gets whether this print job is queued. Such a print job is 91 * ready to be printed and can be started or cancelled. 92 * 93 * @return Whether the print job is queued. 94 * 95 * @see #start() 96 * @see #cancel() 97 */ 98 public boolean isQueued() { 99 return getInfo().getState() == PrintJobInfo.STATE_QUEUED; 100 } 101 102 /** 103 * Gets whether this print job is started. Such a print job is 104 * being printed and can be completed or canceled or failed. 105 * 106 * @return Whether the print job is started. 107 * 108 * @see #complete() 109 * @see #cancel() 110 * @see #fail(CharSequence) 111 */ 112 public boolean isStarted() { 113 return getInfo().getState() == PrintJobInfo.STATE_STARTED; 114 } 115 116 /** 117 * Gets whether this print job is completed. Such a print job 118 * is successfully printed. This is a final state. 119 * 120 * @return Whether the print job is completed. 121 * 122 * @see #complete() 123 */ 124 public boolean isCompleted() { 125 return getInfo().getState() == PrintJobInfo.STATE_COMPLETED; 126 } 127 128 /** 129 * Gets whether this print job is failed. Such a print job is 130 * not successfully printed due to an error. This is a final state. 131 * 132 * @return Whether the print job is failed. 133 * 134 * @see #fail(CharSequence) 135 */ 136 public boolean isFailed() { 137 return getInfo().getState() == PrintJobInfo.STATE_FAILED; 138 } 139 140 /** 141 * Gets whether this print job is cancelled. Such a print job was 142 * cancelled as a result of a user request. This is a final state. 143 * 144 * @return Whether the print job is cancelled. 145 * 146 * @see #cancel() 147 */ 148 public boolean isCancelled() { 149 return getInfo().getState() == PrintJobInfo.STATE_FAILED; 150 } 151 152 /** 153 * Starts the print job. You should call this method if {@link 154 * #isQueued()} returns true and you started printing. 155 * 156 * @return Whether the job as started. 157 * 158 * @see #isQueued() 159 */ 160 public boolean start() { 161 if (isQueued()) { 162 return setState(PrintJobInfo.STATE_STARTED, null); 163 } 164 return false; 165 } 166 167 /** 168 * Completes the print job. You should call this method if {@link 169 * #isStarted()} returns true and you are done printing. 170 * 171 * @return Whether the job as completed. 172 * 173 * @see #isStarted() 174 */ 175 public boolean complete() { 176 if (isStarted()) { 177 return setState(PrintJobInfo.STATE_COMPLETED, null); 178 } 179 return false; 180 } 181 182 /** 183 * Fails the print job. You should call this method if {@link 184 * #isQueued()} or {@link #isStarted()} returns true you failed 185 * while printing. 186 * 187 * @param error The human readable, short, and translated reason 188 * for the failure. 189 * @return Whether the job was failed. 190 * 191 * @see #isQueued() 192 * @see #isStarted() 193 */ 194 public boolean fail(CharSequence error) { 195 if (isQueued() || isStarted()) { 196 return setState(PrintJobInfo.STATE_FAILED, error); 197 } 198 return false; 199 } 200 201 /** 202 * Cancels the print job. You should call this method if {@link 203 * #isQueued()} or {@link #isStarted()} returns true and you canceled 204 * the print job as a response to a call to {@link 205 * PrintService#onRequestCancelPrintJob(PrintJob)}. 206 * 207 * @return Whether the job is canceled. 208 * 209 * @see #isStarted() 210 * @see #isQueued() 211 */ 212 public boolean cancel() { 213 if (isQueued() || isStarted()) { 214 return setState(PrintJobInfo.STATE_CANCELED, null); 215 } 216 return false; 217 } 218 219 /** 220 * Sets a tag that is valid in the context of a {@link PrintService} 221 * and is not interpreted by the system. For example, a print service 222 * may set as a tag the key of the print job returned by a remote 223 * print server, if the printing is off handed to a cloud based service. 224 * 225 * @param tag The tag. 226 * @return True if the tag was set, false otherwise. 227 */ 228 public boolean setTag(String tag) { 229 if (isInImmutableState()) { 230 return false; 231 } 232 try { 233 return mPrintServiceClient.setPrintJobTag(mCachedInfo.getId(), tag); 234 } catch (RemoteException re) { 235 Log.e(LOG_TAG, "Error setting tag for job: " + mCachedInfo.getId(), re); 236 } 237 return false; 238 } 239 240 @Override 241 public boolean equals(Object obj) { 242 if (this == obj) { 243 return true; 244 } 245 if (obj == null) { 246 return false; 247 } 248 if (getClass() != obj.getClass()) { 249 return false; 250 } 251 PrintJob other = (PrintJob) obj; 252 return (mCachedInfo.getId() == other.mCachedInfo.getId()); 253 } 254 255 @Override 256 public int hashCode() { 257 return mCachedInfo.getId(); 258 } 259 260 private boolean isInImmutableState() { 261 final int state = mCachedInfo.getState(); 262 return state == PrintJobInfo.STATE_COMPLETED 263 || state == PrintJobInfo.STATE_CANCELED; 264 } 265 266 private boolean setState(int state, CharSequence error) { 267 try { 268 if (mPrintServiceClient.setPrintJobState(mCachedInfo.getId(), state, error)) { 269 // Best effort - update the state of the cached info since 270 // we may not be able to re-fetch it later if the job gets 271 // removed from the spooler as a result of the state change. 272 mCachedInfo.setState(state); 273 mCachedInfo.setFailureReason(error); 274 return true; 275 } 276 } catch (RemoteException re) { 277 Log.e(LOG_TAG, "Error setting the state of job: " + mCachedInfo.getId(), re); 278 } 279 return false; 280 } 281} 282