Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 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.printservice; |
| 18 | |
| 19 | import android.app.Service; |
| 20 | import android.content.ComponentName; |
| 21 | import android.content.Context; |
| 22 | import android.content.Intent; |
| 23 | import android.os.Handler; |
| 24 | import android.os.IBinder; |
| 25 | import android.os.Looper; |
| 26 | import android.os.Message; |
| 27 | import android.os.RemoteException; |
Svetoslav Ganov | a002715 | 2013-06-25 14:59:53 -0700 | [diff] [blame] | 28 | import android.print.IPrinterDiscoveryObserver; |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 29 | import android.print.PrintJobInfo; |
| 30 | import android.print.PrinterId; |
| 31 | import android.print.PrinterInfo; |
| 32 | import android.util.Log; |
| 33 | |
| 34 | import java.util.ArrayList; |
| 35 | import java.util.Collections; |
| 36 | import java.util.List; |
| 37 | |
| 38 | /** |
| 39 | * <p> |
| 40 | * This is the base class for implementing print services. A print service |
| 41 | * knows how to discover and interact one or more printers via one or more |
| 42 | * protocols. |
| 43 | * </p> |
| 44 | * <h3>Printer discovery</h3> |
| 45 | * <p> |
| 46 | * A print service is responsible for discovering and reporting printers. |
| 47 | * A printer discovery period starts with a call to |
| 48 | * {@link #onStartPrinterDiscovery()} and ends with a call to |
| 49 | * {@link #onStopPrinterDiscovery()}. During a printer discovery |
| 50 | * period the print service reports newly discovered printers by |
Svetoslav Ganov | a002715 | 2013-06-25 14:59:53 -0700 | [diff] [blame] | 51 | * calling {@link #addDiscoveredPrinters(List)} and reports added printers |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 52 | * that disappeared by calling {@link #removeDiscoveredPrinters(List)}. |
| 53 | * Calls to {@link #addDiscoveredPrinters(List)} and |
| 54 | * {@link #removeDiscoveredPrinters(List)} before a call to |
| 55 | * {@link #onStartPrinterDiscovery()} and after a call to |
Svetoslav | fd90651 | 2013-06-24 09:04:48 -0700 | [diff] [blame] | 56 | * {@link #onStopPrinterDiscovery()} are a no-op. |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 57 | * </p> |
| 58 | * <p> |
| 59 | * For every printer discovery period all printers have to be added. Each |
| 60 | * printer known to this print service should be added only once during a |
| 61 | * discovery period, unless it was added and then removed before that. |
| 62 | * Only an already added printer can be removed. |
| 63 | * </p> |
| 64 | * <h3>Print jobs</h3> |
| 65 | * <p> |
| 66 | * When a new print job targeted to the printers managed by this print |
| 67 | * service is queued, i.e. ready for processing by the print service, |
| 68 | * a call to {@link #onPrintJobQueued(PrintJob)} is made and the print |
| 69 | * service may handle it immediately or schedule that for an appropriate |
| 70 | * time in the future. The list of all print jobs for this service |
Svetoslav Ganov | a002715 | 2013-06-25 14:59:53 -0700 | [diff] [blame] | 71 | * are be available by calling {@link #getPrintJobs()}. |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 72 | * </p> |
| 73 | * <p> |
| 74 | * A print service is responsible for setting the print job state as |
| 75 | * appropriate while processing it. Initially, a print job is in a |
| 76 | * {@link PrintJobInfo#STATE_QUEUED} state which means that the data to |
| 77 | * be printed is spooled by the system and the print service can obtain |
Svetoslav Ganov | a002715 | 2013-06-25 14:59:53 -0700 | [diff] [blame] | 78 | * that data by calling {@link PrintJob#getDocument()}. A queued print |
| 79 | * job's {@link PrintJob#isQueued()} method returns true. |
| 80 | * </p> |
| 81 | * <p> |
| 82 | * After the print service starts printing the data it should set the |
| 83 | * print job state to {@link PrintJobInfo#STATE_STARTED} by calling |
| 84 | * {@link PrintJob#start()}. Upon successful completion, the print job |
| 85 | * state has to be set to {@link PrintJobInfo#STATE_COMPLETED} by calling |
| 86 | * {@link PrintJob#complete()}. In case of a failure, the print job |
| 87 | * state should be set to {@link PrintJobInfo#STATE_FAILED} by calling |
| 88 | * {@link PrintJob#fail(CharSequence)}. If a print job is in a |
| 89 | * {@link PrintJobInfo#STATE_STARTED} state, i.e. {@link PrintJob#isStarted()} |
| 90 | * return true, and the user requests to cancel it, the print service will |
| 91 | * receive a call to {@link #onRequestCancelPrintJob(PrintJob)} which |
| 92 | * requests from the service to do a best effort in canceling the job. In |
| 93 | * case the job is successfully canceled, its state has to be set to |
| 94 | * {@link PrintJobInfo#STATE_CANCELED}. by calling {@link PrintJob#cancel()}. |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 95 | * </p> |
| 96 | * <h3>Lifecycle</h3> |
| 97 | * <p> |
| 98 | * The lifecycle of a print service is managed exclusively by the system |
| 99 | * and follows the established service lifecycle. Additionally, starting |
| 100 | * or stopping a print service is triggered exclusively by an explicit |
| 101 | * user action through enabling or disabling it in the device settings. |
| 102 | * After the system binds to a print service, it calls {@link #onConnected()}. |
| 103 | * This method can be overriden by clients to perform post binding setup. |
| 104 | * Also after the system unbinds from a print service, it calls |
| 105 | * {@link #onDisconnected()}. This method can be overriden by clients to |
| 106 | * perform post unbinding cleanup. |
| 107 | * </p> |
| 108 | * <h3>Declaration</h3> |
| 109 | * <p> |
| 110 | * A print service is declared as any other service in an AndroidManifest.xml |
| 111 | * but it must also specify that it handles the {@link android.content.Intent} |
| 112 | * with action {@link #SERVICE_INTERFACE}. Failure to declare this intent |
| 113 | * will cause the system to ignore the print service. Additionally, a print |
| 114 | * service must request the {@link android.Manifest.permission#BIND_PRINT_SERVICE} |
| 115 | * permission to ensure that only the system can bind to it. Failure to |
| 116 | * declare this intent will cause the system to ignore the print service. |
| 117 | * Following is an example declaration: |
| 118 | * </p> |
| 119 | * <pre> |
| 120 | * <service android:name=".MyPrintService" |
| 121 | * android:permission="android.permission.BIND_PRINT_SERVICE"> |
| 122 | * <intent-filter> |
| 123 | * <action android:name="android.printservice.PrintService" /> |
| 124 | * </intent-filter> |
| 125 | * . . . |
| 126 | * </service> |
| 127 | * </pre> |
| 128 | * <h3>Configuration</h3> |
| 129 | * <p> |
| 130 | * A print service can be configured by specifying an optional settings |
| 131 | * activity which exposes service specific options, an optional add |
Svetoslav Ganov | a002715 | 2013-06-25 14:59:53 -0700 | [diff] [blame] | 132 | * prints activity which is used for manual addition of printers, vendor |
| 133 | * name ,etc. It is a responsibility of the system to launch the settings |
| 134 | * and add printers activities when appropriate. |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 135 | * </p> |
| 136 | * <p> |
| 137 | * A print service is configured by providing a |
| 138 | * {@link #SERVICE_META_DATA meta-data} entry in the manifest when declaring |
| 139 | * the service. A service declaration with a meta-data tag is presented |
| 140 | * below: |
| 141 | * <pre> <service android:name=".MyPrintService" |
| 142 | * android:permission="android.permission.BIND_PRINT_SERVICE"> |
| 143 | * <intent-filter> |
| 144 | * <action android:name="android.printservice.PrintService" /> |
| 145 | * </intent-filter> |
| 146 | * <meta-data android:name="android.printservice" android:resource="@xml/printservice" /> |
| 147 | * </service></pre> |
| 148 | * </p> |
| 149 | * <p> |
| 150 | * For more details refer to {@link #SERVICE_META_DATA} and |
| 151 | * <code><{@link android.R.styleable#PrintService print-service}></code>. |
| 152 | * </p> |
| 153 | */ |
| 154 | public abstract class PrintService extends Service { |
| 155 | |
Svetoslav Ganov | a002715 | 2013-06-25 14:59:53 -0700 | [diff] [blame] | 156 | private static final String LOG_TAG = "PrintService"; |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 157 | |
| 158 | /** |
| 159 | * The {@link Intent} action that must be declared as handled by a service |
| 160 | * in its manifest to allow the system to recognize it as a print service. |
| 161 | */ |
| 162 | public static final String SERVICE_INTERFACE = "android.printservice.PrintService"; |
| 163 | |
| 164 | /** |
| 165 | * Name under which a PrintService component publishes additional information |
| 166 | * about itself. This meta-data must reference an XML resource containing a |
| 167 | * <code><{@link android.R.styleable#PrintService print-service}></code> |
| 168 | * tag. This is a a sample XML file configuring a print service: |
| 169 | * <pre> <print-service |
Svetoslav Ganov | a002715 | 2013-06-25 14:59:53 -0700 | [diff] [blame] | 170 | * android:vendor="SomeVendor" |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 171 | * android:settingsActivity="foo.bar.MySettingsActivity" |
| 172 | * andorid:addPrintersActivity="foo.bar.MyAddPrintersActivity." |
| 173 | * . . . |
| 174 | * /></pre> |
| 175 | */ |
| 176 | public static final String SERVICE_META_DATA = "android.printservice"; |
| 177 | |
| 178 | private final Object mLock = new Object(); |
| 179 | |
| 180 | private Handler mHandler; |
| 181 | |
| 182 | private IPrintServiceClient mClient; |
| 183 | |
Svetoslav Ganov | a002715 | 2013-06-25 14:59:53 -0700 | [diff] [blame] | 184 | private IPrinterDiscoveryObserver mDiscoveryObserver; |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 185 | |
| 186 | @Override |
| 187 | protected void attachBaseContext(Context base) { |
| 188 | super.attachBaseContext(base); |
| 189 | mHandler = new MyHandler(base.getMainLooper()); |
| 190 | } |
| 191 | |
| 192 | /** |
| 193 | * The system has connected to this service. |
| 194 | */ |
| 195 | protected void onConnected() { |
| 196 | /* do nothing */ |
| 197 | } |
| 198 | |
| 199 | /** |
| 200 | * The system has disconnected from this service. |
| 201 | */ |
| 202 | protected void onDisconnected() { |
| 203 | /* do nothing */ |
| 204 | } |
| 205 | |
| 206 | /** |
| 207 | * Callback requesting from this service to start printer discovery. |
| 208 | * At the end of the printer discovery period the system will call |
Svetoslav | fd90651 | 2013-06-24 09:04:48 -0700 | [diff] [blame] | 209 | * {@link #onStopPrinterDiscovery()}. Discovered printers should be |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 210 | * reported by calling #addDiscoveredPrinters(List) and reported ones |
| 211 | * that disappear should be reported by calling |
| 212 | * {@link #removeDiscoveredPrinters(List)}. |
| 213 | * |
| 214 | * @see #onStopPrinterDiscovery() |
| 215 | * @see #addDiscoveredPrinters(List) |
| 216 | * @see #removeDiscoveredPrinters(List) |
| 217 | */ |
| 218 | protected abstract void onStartPrinterDiscovery(); |
| 219 | |
| 220 | /** |
| 221 | * Callback requesting from this service to stop printer discovery. |
| 222 | * |
| 223 | * @see #onStartPrinterDiscovery() |
| 224 | * @see #addDiscoveredPrinters(List) |
| 225 | * @see #removeDiscoveredPrinters(List) |
| 226 | */ |
| 227 | protected abstract void onStopPrinterDiscovery(); |
| 228 | |
| 229 | /** |
| 230 | * Adds discovered printers. This method should be called during a |
| 231 | * printer discovery period, i.e. after a call to |
| 232 | * {@link #onStartPrinterDiscovery()} and before the corresponding |
| 233 | * call to {@link #onStopPrinterDiscovery()}, otherwise it does nothing. |
| 234 | * <p> |
| 235 | * <strong>Note:</strong> For every printer discovery period all |
| 236 | * printers have to be added. You can call this method as many times as |
| 237 | * necessary during the discovery period but should not pass in already |
| 238 | * added printers. If a printer is already added in the same printer |
Svetoslav Ganov | a002715 | 2013-06-25 14:59:53 -0700 | [diff] [blame] | 239 | * discovery period, it will be ignored. If you want to update an already |
| 240 | * added printer, you should removed it and then re-add it. |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 241 | * </p> |
| 242 | * |
| 243 | * @param printers A list with discovered printers. |
| 244 | * |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 245 | * @see #removeDiscoveredPrinters(List) |
| 246 | * @see #onStartPrinterDiscovery() |
| 247 | * @see #onStopPrinterDiscovery() |
Svetoslav Ganov | a002715 | 2013-06-25 14:59:53 -0700 | [diff] [blame] | 248 | * |
| 249 | * @throws IllegalStateException If this service is not connected. |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 250 | */ |
| 251 | public final void addDiscoveredPrinters(List<PrinterInfo> printers) { |
Svetoslav Ganov | a002715 | 2013-06-25 14:59:53 -0700 | [diff] [blame] | 252 | final IPrinterDiscoveryObserver observer; |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 253 | synchronized (mLock) { |
Svetoslav Ganov | a002715 | 2013-06-25 14:59:53 -0700 | [diff] [blame] | 254 | throwIfNotConnectedLocked(); |
| 255 | observer = mDiscoveryObserver; |
| 256 | } |
| 257 | if (observer != null) { |
| 258 | try { |
| 259 | observer.addDiscoveredPrinters(printers); |
| 260 | } catch (RemoteException re) { |
| 261 | Log.e(LOG_TAG, "Error adding discovered printers", re); |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 262 | } |
| 263 | } |
| 264 | } |
| 265 | |
| 266 | /** |
| 267 | * Removes discovered printers given their ids. This method should be called |
| 268 | * during a printer discovery period, i.e. after a call to |
| 269 | * {@link #onStartPrinterDiscovery()} and before the corresponding |
| 270 | * call to {@link #onStopPrinterDiscovery()}, otherwise it does nothing. |
| 271 | * <p> |
| 272 | * For every printer discovery period all printers have to be added. You |
| 273 | * should remove only printers that were added in this printer discovery |
| 274 | * period by a call to {@link #addDiscoveredPrinters(List)}. You can call |
| 275 | * this method as many times as necessary during the discovery period |
| 276 | * but should not pass in already removed printer ids. If a printer with |
| 277 | * a given id is already removed in the same discovery period, it will |
Svetoslav Ganov | a002715 | 2013-06-25 14:59:53 -0700 | [diff] [blame] | 278 | * be ignored. If you want to update an already added printer, you should |
| 279 | * removed it and then re-add it. |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 280 | * </p> |
| 281 | * |
| 282 | * @param printerIds A list with disappeared printer ids. |
| 283 | * |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 284 | * @see #addDiscoveredPrinters(List) |
| 285 | * @see #onStartPrinterDiscovery() |
| 286 | * @see #onStopPrinterDiscovery() |
Svetoslav Ganov | a002715 | 2013-06-25 14:59:53 -0700 | [diff] [blame] | 287 | * |
| 288 | * @throws IllegalStateException If this service is not connected. |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 289 | */ |
| 290 | public final void removeDiscoveredPrinters(List<PrinterId> printerIds) { |
Svetoslav Ganov | a002715 | 2013-06-25 14:59:53 -0700 | [diff] [blame] | 291 | final IPrinterDiscoveryObserver observer; |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 292 | synchronized (mLock) { |
Svetoslav Ganov | a002715 | 2013-06-25 14:59:53 -0700 | [diff] [blame] | 293 | throwIfNotConnectedLocked(); |
| 294 | observer = mDiscoveryObserver; |
| 295 | } |
| 296 | if (observer != null) { |
| 297 | try { |
| 298 | observer.removeDiscoveredPrinters(printerIds); |
| 299 | } catch (RemoteException re) { |
| 300 | Log.e(LOG_TAG, "Error removing discovered printers", re); |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 301 | } |
| 302 | } |
| 303 | } |
| 304 | |
| 305 | /** |
| 306 | * Called when canceling of a print job is requested. The service |
Svetoslav Ganov | a002715 | 2013-06-25 14:59:53 -0700 | [diff] [blame] | 307 | * should do best effort to fulfill the request. After the cancellation |
| 308 | * is performed, the print job should be set to a cancelled state by |
| 309 | * calling {@link PrintJob#cancel()}. |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 310 | * |
| 311 | * @param printJob The print job to be canceled. |
| 312 | */ |
| 313 | protected void onRequestCancelPrintJob(PrintJob printJob) { |
| 314 | } |
| 315 | |
| 316 | /** |
| 317 | * Called when there is a queued print job for one of the printers |
| 318 | * managed by this print service. A queued print job is ready for |
| 319 | * processing by a print service which can get the data to be printed |
Svetoslav Ganov | a002715 | 2013-06-25 14:59:53 -0700 | [diff] [blame] | 320 | * by calling {@link PrintJob#getDocument()}. This service may start |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 321 | * processing the passed in print job or schedule handling of queued |
| 322 | * print jobs at a convenient time. The service can get the print |
| 323 | * jobs by a call to {@link #getPrintJobs()} and examine their state |
Svetoslav Ganov | a002715 | 2013-06-25 14:59:53 -0700 | [diff] [blame] | 324 | * to find the ones with state {@link PrintJobInfo#STATE_QUEUED} by |
| 325 | * calling {@link PrintJob#isQueued()}. |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 326 | * |
| 327 | * @param printJob The new queued print job. |
| 328 | * |
| 329 | * @see #getPrintJobs() |
| 330 | */ |
| 331 | protected abstract void onPrintJobQueued(PrintJob printJob); |
| 332 | |
| 333 | /** |
| 334 | * Gets the print jobs for the printers managed by this service. |
| 335 | * |
| 336 | * @return The print jobs. |
| 337 | * |
| 338 | * @throws IllegalStateException If this service is not connected. |
| 339 | */ |
| 340 | public final List<PrintJob> getPrintJobs() { |
Svetoslav Ganov | a002715 | 2013-06-25 14:59:53 -0700 | [diff] [blame] | 341 | final IPrintServiceClient client; |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 342 | synchronized (mLock) { |
Svetoslav Ganov | a002715 | 2013-06-25 14:59:53 -0700 | [diff] [blame] | 343 | throwIfNotConnectedLocked(); |
| 344 | client = mClient; |
| 345 | } |
| 346 | if (client == null) { |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 347 | return Collections.emptyList(); |
| 348 | } |
Svetoslav Ganov | a002715 | 2013-06-25 14:59:53 -0700 | [diff] [blame] | 349 | try { |
| 350 | List<PrintJob> printJobs = null; |
| 351 | List<PrintJobInfo> printJobInfos = client.getPrintJobInfos(); |
| 352 | if (printJobInfos != null) { |
| 353 | final int printJobInfoCount = printJobInfos.size(); |
| 354 | printJobs = new ArrayList<PrintJob>(printJobInfoCount); |
| 355 | for (int i = 0; i < printJobInfoCount; i++) { |
| 356 | printJobs.add(new PrintJob(printJobInfos.get(i), client)); |
| 357 | } |
| 358 | } |
| 359 | if (printJobs != null) { |
| 360 | return printJobs; |
| 361 | } |
| 362 | } catch (RemoteException re) { |
| 363 | Log.e(LOG_TAG, "Error calling getPrintJobs()", re); |
| 364 | } |
| 365 | return Collections.emptyList(); |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 366 | } |
| 367 | |
| 368 | /** |
| 369 | * Generates a global printer id from a local id. The local id is unique |
| 370 | * only within this print service. |
| 371 | * |
| 372 | * @param localId The local id. |
| 373 | * @return Global printer id. |
| 374 | */ |
| 375 | public final PrinterId generatePrinterId(String localId) { |
| 376 | return new PrinterId(new ComponentName(getPackageName(), |
| 377 | getClass().getName()), localId); |
| 378 | } |
| 379 | |
| 380 | @Override |
| 381 | public final IBinder onBind(Intent intent) { |
| 382 | return new IPrintService.Stub() { |
| 383 | @Override |
| 384 | public void setClient(IPrintServiceClient client) { |
| 385 | mHandler.obtainMessage(MyHandler.MESSAGE_SET_CLEINT, client).sendToTarget(); |
| 386 | } |
| 387 | |
| 388 | @Override |
Svetoslav Ganov | a002715 | 2013-06-25 14:59:53 -0700 | [diff] [blame] | 389 | public void startPrinterDiscovery(IPrinterDiscoveryObserver observer) { |
| 390 | mHandler.obtainMessage(MyHandler.MESSAGE_START_PRINTER_DISCOVERY, |
| 391 | observer).sendToTarget(); |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 392 | } |
| 393 | |
| 394 | @Override |
| 395 | public void stopPrinterDiscovery() { |
| 396 | mHandler.sendEmptyMessage(MyHandler.MESSAGE_STOP_PRINTER_DISCOVERY); |
| 397 | } |
| 398 | |
| 399 | @Override |
Svetoslav Ganov | a002715 | 2013-06-25 14:59:53 -0700 | [diff] [blame] | 400 | public void requestCancelPrintJob(PrintJobInfo printJobInfo) { |
| 401 | mHandler.obtainMessage(MyHandler.MESSAGE_CANCEL_PRINTJOB, |
| 402 | printJobInfo).sendToTarget(); |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 403 | } |
| 404 | |
| 405 | @Override |
Svetoslav Ganov | a002715 | 2013-06-25 14:59:53 -0700 | [diff] [blame] | 406 | public void onPrintJobQueued(PrintJobInfo printJobInfo) { |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 407 | mHandler.obtainMessage(MyHandler.MESSAGE_ON_PRINTJOB_QUEUED, |
Svetoslav Ganov | a002715 | 2013-06-25 14:59:53 -0700 | [diff] [blame] | 408 | printJobInfo).sendToTarget(); |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 409 | } |
| 410 | }; |
| 411 | } |
| 412 | |
Svetoslav Ganov | a002715 | 2013-06-25 14:59:53 -0700 | [diff] [blame] | 413 | private void throwIfNotConnectedLocked() { |
| 414 | if (mClient == null) { |
| 415 | throw new IllegalStateException("Print serivice not connected"); |
| 416 | } |
| 417 | } |
| 418 | |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 419 | private final class MyHandler extends Handler { |
| 420 | public static final int MESSAGE_START_PRINTER_DISCOVERY = 1; |
| 421 | public static final int MESSAGE_STOP_PRINTER_DISCOVERY = 2; |
| 422 | public static final int MESSAGE_CANCEL_PRINTJOB = 3; |
| 423 | public static final int MESSAGE_ON_PRINTJOB_QUEUED = 4; |
| 424 | public static final int MESSAGE_SET_CLEINT = 5; |
| 425 | |
| 426 | public MyHandler(Looper looper) { |
| 427 | super(looper, null, true); |
| 428 | } |
| 429 | |
| 430 | @Override |
| 431 | public void handleMessage(Message message) { |
| 432 | final int action = message.what; |
| 433 | switch (action) { |
| 434 | case MESSAGE_START_PRINTER_DISCOVERY: { |
| 435 | synchronized (mLock) { |
Svetoslav Ganov | a002715 | 2013-06-25 14:59:53 -0700 | [diff] [blame] | 436 | mDiscoveryObserver = (IPrinterDiscoveryObserver) message.obj; |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 437 | } |
| 438 | onStartPrinterDiscovery(); |
| 439 | } break; |
| 440 | |
| 441 | case MESSAGE_STOP_PRINTER_DISCOVERY: { |
| 442 | synchronized (mLock) { |
Svetoslav Ganov | a002715 | 2013-06-25 14:59:53 -0700 | [diff] [blame] | 443 | mDiscoveryObserver = null; |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 444 | } |
| 445 | onStopPrinterDiscovery(); |
| 446 | } break; |
| 447 | |
| 448 | case MESSAGE_CANCEL_PRINTJOB: { |
Svetoslav Ganov | a002715 | 2013-06-25 14:59:53 -0700 | [diff] [blame] | 449 | PrintJobInfo printJobInfo = (PrintJobInfo) message.obj; |
| 450 | onRequestCancelPrintJob(new PrintJob(printJobInfo, mClient)); |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 451 | } break; |
| 452 | |
| 453 | case MESSAGE_ON_PRINTJOB_QUEUED: { |
Svetoslav Ganov | a002715 | 2013-06-25 14:59:53 -0700 | [diff] [blame] | 454 | PrintJobInfo printJobInfo = (PrintJobInfo) message.obj; |
| 455 | onPrintJobQueued(new PrintJob(printJobInfo, mClient)); |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 456 | } break; |
| 457 | |
| 458 | case MESSAGE_SET_CLEINT: { |
| 459 | IPrintServiceClient client = (IPrintServiceClient) message.obj; |
| 460 | synchronized (mLock) { |
| 461 | mClient = client; |
| 462 | if (client == null) { |
Svetoslav Ganov | a002715 | 2013-06-25 14:59:53 -0700 | [diff] [blame] | 463 | mDiscoveryObserver = null; |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 464 | } |
| 465 | } |
| 466 | if (client != null) { |
| 467 | onConnected(); |
| 468 | } else { |
Svetoslav Ganov | 4b9a4d1 | 2013-06-11 15:20:06 -0700 | [diff] [blame] | 469 | onDisconnected(); |
| 470 | } |
| 471 | } break; |
| 472 | |
| 473 | default: { |
| 474 | throw new IllegalArgumentException("Unknown message: " + action); |
| 475 | } |
| 476 | } |
| 477 | } |
| 478 | } |
| 479 | } |