blob: 5f9a730f3f4a331d7374429b2b553d27d221febe [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.printservice;
18
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -070019import android.os.RemoteException;
20import android.print.PrintJobInfo;
21import android.util.Log;
22
23/**
Svetoslav Ganov798bed62013-08-11 12:29:39 -070024 * 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.
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -070027 */
28public final class PrintJob {
29
30 private static final String LOG_TAG = "PrintJob";
31
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -070032 private final IPrintServiceClient mPrintServiceClient;
33
Svetoslav Ganova0027152013-06-25 14:59:53 -070034 private final PrintDocument mDocument;
35
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -070036 private PrintJobInfo mCachedInfo;
37
Svetoslav Ganova0027152013-06-25 14:59:53 -070038 PrintJob(PrintJobInfo jobInfo, IPrintServiceClient client) {
39 mCachedInfo = jobInfo;
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -070040 mPrintServiceClient = client;
Svetoslav Ganov798bed62013-08-11 12:29:39 -070041 mDocument = new PrintDocument(mCachedInfo.getId(), client,
42 jobInfo.getDocumentInfo());
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -070043 }
44
45 /**
46 * Gets the unique print job id.
47 *
48 * @return The id.
49 */
50 public int getId() {
Svetoslav Ganova0027152013-06-25 14:59:53 -070051 return mCachedInfo.getId();
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -070052 }
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
Svetoslavfd906512013-06-24 09:04:48 -070059 * info object that reflects the current print job state.
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -070060 * </p>
61 *
62 * @return The print job info.
63 */
64 public PrintJobInfo getInfo() {
Svetoslav Ganov85b1f882013-07-24 17:00:06 -070065 if (isInImmutableState()) {
66 return mCachedInfo;
67 }
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -070068 PrintJobInfo info = null;
69 try {
Svetoslav Ganova0027152013-06-25 14:59:53 -070070 info = mPrintServiceClient.getPrintJobInfo(mCachedInfo.getId());
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -070071 } catch (RemoteException re) {
Svetoslav Ganova0027152013-06-25 14:59:53 -070072 Log.e(LOG_TAG, "Couldn't get info for job: " + mCachedInfo.getId(), re);
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -070073 }
74 if (info != null) {
75 mCachedInfo = info;
76 }
77 return mCachedInfo;
78 }
79
80 /**
Svetoslav Ganov798bed62013-08-11 12:29:39 -070081 * Gets the printed document.
Svetoslav Ganova0027152013-06-25 14:59:53 -070082 *
83 * @return The document.
84 */
85 public PrintDocument getDocument() {
86 return mDocument;
87 }
88
89 /**
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -070090 * Gets whether this print job is queued. Such a print job is
Svetoslav Ganov798bed62013-08-11 12:29:39 -070091 * ready to be printed and can be started or cancelled.
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -070092 *
93 * @return Whether the print job is queued.
94 *
95 * @see #start()
Svetoslav Ganov798bed62013-08-11 12:29:39 -070096 * @see #cancel()
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -070097 */
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()
Svetoslavfd906512013-06-24 09:04:48 -0700110 * @see #fail(CharSequence)
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700111 */
112 public boolean isStarted() {
Svetoslav Ganova0027152013-06-25 14:59:53 -0700113 return getInfo().getState() == PrintJobInfo.STATE_STARTED;
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700114 }
115
116 /**
Svetoslav Ganov798bed62013-08-11 12:29:39 -0700117 * 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 /**
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700153 * 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()) {
Svetoslav Ganov8c433762013-08-02 14:22:19 -0700162 return setState(PrintJobInfo.STATE_STARTED, null);
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700163 }
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()) {
Svetoslav Ganov8c433762013-08-02 14:22:19 -0700177 return setState(PrintJobInfo.STATE_COMPLETED, null);
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700178 }
179 return false;
180 }
181
182 /**
183 * Fails the print job. You should call this method if {@link
Svetoslav Ganov8c433762013-08-02 14:22:19 -0700184 * #isQueued()} or {@link #isStarted()} returns true you failed
185 * while printing.
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700186 *
Svetoslav Ganov8c433762013-08-02 14:22:19 -0700187 * @param error The human readable, short, and translated reason
188 * for the failure.
Svetoslavfd906512013-06-24 09:04:48 -0700189 * @return Whether the job was failed.
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700190 *
Svetoslav Ganov8c433762013-08-02 14:22:19 -0700191 * @see #isQueued()
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700192 * @see #isStarted()
193 */
194 public boolean fail(CharSequence error) {
Svetoslav Ganov8c433762013-08-02 14:22:19 -0700195 if (isQueued() || isStarted()) {
196 return setState(PrintJobInfo.STATE_FAILED, error);
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700197 }
198 return false;
199 }
200
201 /**
202 * Cancels the print job. You should call this method if {@link
Svetoslav Ganov8c433762013-08-02 14:22:19 -0700203 * #isQueued()} or {@link #isStarted()} returns true and you canceled
Svetoslav Ganov798bed62013-08-11 12:29:39 -0700204 * the print job as a response to a call to {@link
205 * PrintService#onRequestCancelPrintJob(PrintJob)}.
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700206 *
Svetoslav Ganov798bed62013-08-11 12:29:39 -0700207 * @return Whether the job is canceled.
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700208 *
209 * @see #isStarted()
Svetoslav Ganov798bed62013-08-11 12:29:39 -0700210 * @see #isQueued()
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700211 */
212 public boolean cancel() {
Svetoslav Ganov8c433762013-08-02 14:22:19 -0700213 if (isQueued() || isStarted()) {
214 return setState(PrintJobInfo.STATE_CANCELED, null);
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700215 }
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) {
Svetoslav Ganov85b1f882013-07-24 17:00:06 -0700229 if (isInImmutableState()) {
230 return false;
231 }
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700232 try {
Svetoslav Ganova0027152013-06-25 14:59:53 -0700233 return mPrintServiceClient.setPrintJobTag(mCachedInfo.getId(), tag);
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700234 } catch (RemoteException re) {
Svetoslav Ganova0027152013-06-25 14:59:53 -0700235 Log.e(LOG_TAG, "Error setting tag for job: " + mCachedInfo.getId(), re);
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700236 }
237 return false;
238 }
239
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700240 @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;
Svetoslav Ganova0027152013-06-25 14:59:53 -0700252 return (mCachedInfo.getId() == other.mCachedInfo.getId());
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700253 }
254
255 @Override
256 public int hashCode() {
Svetoslav Ganova0027152013-06-25 14:59:53 -0700257 return mCachedInfo.getId();
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700258 }
259
Svetoslav Ganov85b1f882013-07-24 17:00:06 -0700260 private boolean isInImmutableState() {
261 final int state = mCachedInfo.getState();
262 return state == PrintJobInfo.STATE_COMPLETED
263 || state == PrintJobInfo.STATE_CANCELED;
264 }
265
Svetoslav Ganov8c433762013-08-02 14:22:19 -0700266 private boolean setState(int state, CharSequence error) {
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700267 try {
Svetoslav Ganov8c433762013-08-02 14:22:19 -0700268 if (mPrintServiceClient.setPrintJobState(mCachedInfo.getId(), state, error)) {
Svetoslav Ganova0027152013-06-25 14:59:53 -0700269 // 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);
Svetoslav Ganov8c433762013-08-02 14:22:19 -0700273 mCachedInfo.setFailureReason(error);
Svetoslav Ganova0027152013-06-25 14:59:53 -0700274 return true;
275 }
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700276 } catch (RemoteException re) {
Svetoslav Ganova0027152013-06-25 14:59:53 -0700277 Log.e(LOG_TAG, "Error setting the state of job: " + mCachedInfo.getId(), re);
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700278 }
279 return false;
280 }
281}