/* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.printservice; import android.app.Service; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.print.PrintJobInfo; import android.print.PrinterId; import android.print.PrinterInfo; import android.util.Log; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** *
* This is the base class for implementing print services. A print service * knows how to discover and interact one or more printers via one or more * protocols. *
** A print service is responsible for discovering and reporting printers. * A printer discovery period starts with a call to * {@link #onStartPrinterDiscovery()} and ends with a call to * {@link #onStopPrinterDiscovery()}. During a printer discovery * period the print service reports newly discovered printers by * calling {@link #addDiscoveredPrinters(List)} and added printers * that disappeared by calling {@link #removeDiscoveredPrinters(List)}. * Calls to {@link #addDiscoveredPrinters(List)} and * {@link #removeDiscoveredPrinters(List)} before a call to * {@link #onStartPrinterDiscovery()} and after a call to * {@link #onStopPrinterDiscovery()} are a no-op. *
** For every printer discovery period all printers have to be added. Each * printer known to this print service should be added only once during a * discovery period, unless it was added and then removed before that. * Only an already added printer can be removed. *
** When a new print job targeted to the printers managed by this print * service is queued, i.e. ready for processing by the print service, * a call to {@link #onPrintJobQueued(PrintJob)} is made and the print * service may handle it immediately or schedule that for an appropriate * time in the future. The list of all print jobs for this service * are be available by calling {@link #getPrintJobs()}. A queued print * job is one whose {@link PrintJob#isQueued()} return true. *
** A print service is responsible for setting the print job state as * appropriate while processing it. Initially, a print job is in a * {@link PrintJobInfo#STATE_QUEUED} state which means that the data to * be printed is spooled by the system and the print service can obtain * that data by calling {@link PrintJob#getData()}. After the print * service starts printing the data it should set the print job state * to {@link PrintJobInfo#STATE_STARTED}. Upon successful completion, the * print job state has to be set to {@link PrintJobInfo#STATE_COMPLETED}. * In a case of a failure, the print job state should be set to * {@link PrintJobInfo#STATE_FAILED}. If a print job is in a * {@link PrintJobInfo#STATE_STARTED} state and the user requests to * cancel it, the print service will receive a call to * {@link #onRequestCancelPrintJob(PrintJob)} which requests from the * service to do a best effort in canceling the job. In case the job * is successfully canceled, its state has to be set to * {@link PrintJobInfo#STATE_CANCELED}. *
** The lifecycle of a print service is managed exclusively by the system * and follows the established service lifecycle. Additionally, starting * or stopping a print service is triggered exclusively by an explicit * user action through enabling or disabling it in the device settings. * After the system binds to a print service, it calls {@link #onConnected()}. * This method can be overriden by clients to perform post binding setup. * Also after the system unbinds from a print service, it calls * {@link #onDisconnected()}. This method can be overriden by clients to * perform post unbinding cleanup. *
** A print service is declared as any other service in an AndroidManifest.xml * but it must also specify that it handles the {@link android.content.Intent} * with action {@link #SERVICE_INTERFACE}. Failure to declare this intent * will cause the system to ignore the print service. Additionally, a print * service must request the {@link android.Manifest.permission#BIND_PRINT_SERVICE} * permission to ensure that only the system can bind to it. Failure to * declare this intent will cause the system to ignore the print service. * Following is an example declaration: *
** <service android:name=".MyPrintService" * android:permission="android.permission.BIND_PRINT_SERVICE"> * <intent-filter> * <action android:name="android.printservice.PrintService" /> * </intent-filter> * . . . * </service> **
* A print service can be configured by specifying an optional settings * activity which exposes service specific options, an optional add * prints activity which is used for manual addition of printers, etc. * It is a responsibility of the system to launch the settings and add * printers activities when appropriate. *
** A print service is configured by providing a * {@link #SERVICE_META_DATA meta-data} entry in the manifest when declaring * the service. A service declaration with a meta-data tag is presented * below: *
<service android:name=".MyPrintService" * android:permission="android.permission.BIND_PRINT_SERVICE"> * <intent-filter> * <action android:name="android.printservice.PrintService" /> * </intent-filter> * <meta-data android:name="android.printservice" android:resource="@xml/printservice" /> * </service>* *
* For more details refer to {@link #SERVICE_META_DATA} and
* <{@link android.R.styleable#PrintService print-service}>
.
*
<{@link android.R.styleable#PrintService print-service}>
* tag. This is a a sample XML file configuring a print service:
* <print-service * android:settingsActivity="foo.bar.MySettingsActivity" * andorid:addPrintersActivity="foo.bar.MyAddPrintersActivity." * . . . * />*/ public static final String SERVICE_META_DATA = "android.printservice"; private final Object mLock = new Object(); private Handler mHandler; private IPrintServiceClient mClient; private boolean mDiscoveringPrinters; @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); mHandler = new MyHandler(base.getMainLooper()); } /** * The system has connected to this service. */ protected void onConnected() { /* do nothing */ } /** * The system has disconnected from this service. */ protected void onDisconnected() { /* do nothing */ } /** * Callback requesting from this service to start printer discovery. * At the end of the printer discovery period the system will call * {@link #onStopPrinterDiscovery()}. Discovered printers should be * reported by calling #addDiscoveredPrinters(List) and reported ones * that disappear should be reported by calling * {@link #removeDiscoveredPrinters(List)}. * * @see #onStopPrinterDiscovery() * @see #addDiscoveredPrinters(List) * @see #removeDiscoveredPrinters(List) */ protected abstract void onStartPrinterDiscovery(); /** * Callback requesting from this service to stop printer discovery. * * @see #onStartPrinterDiscovery() * @see #addDiscoveredPrinters(List) * @see #removeDiscoveredPrinters(List) */ protected abstract void onStopPrinterDiscovery(); /** * Adds discovered printers. This method should be called during a * printer discovery period, i.e. after a call to * {@link #onStartPrinterDiscovery()} and before the corresponding * call to {@link #onStopPrinterDiscovery()}, otherwise it does nothing. *
* Note: For every printer discovery period all * printers have to be added. You can call this method as many times as * necessary during the discovery period but should not pass in already * added printers. If a printer is already added in the same printer * discovery period, it will be ignored. *
* * @param printers A list with discovered printers. * * @throws IllegalStateException If this service is not connected. * * @see #removeDiscoveredPrinters(List) * @see #onStartPrinterDiscovery() * @see #onStopPrinterDiscovery() */ public final void addDiscoveredPrinters(List* For every printer discovery period all printers have to be added. You * should remove only printers that were added in this printer discovery * period by a call to {@link #addDiscoveredPrinters(List)}. You can call * this method as many times as necessary during the discovery period * but should not pass in already removed printer ids. If a printer with * a given id is already removed in the same discovery period, it will * be ignored. *
* * @param printerIds A list with disappeared printer ids. * * @throws IllegalStateException If this service is not connected. * * @see #addDiscoveredPrinters(List) * @see #onStartPrinterDiscovery() * @see #onStopPrinterDiscovery() */ public final void removeDiscoveredPrinters(List