PrintDocumentAdapter.java revision 4d4c66dd38e940082e385b49a33f4022ab04c738
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.print;
18
19import android.os.Bundle;
20import android.os.CancellationSignal;
21import android.os.ParcelFileDescriptor;
22
23/**
24 * Base class that provides the content of a document to be printed.
25 *
26 * <h3>Lifecycle</h3>
27 * <p>
28 * <ul>
29 * <li>
30 * Initially, you will receive a call to {@link #onStart()}. This callback
31 * can be used to allocate resources.
32 * </li>
33 * <li>
34 * Next, you will get one or more calls to {@link #onLayout(PrintAttributes,
35 * PrintAttributes, CancellationSignal, LayoutResultCallback, Bundle)} to
36 * inform you that the print attributes (page size, density, etc) changed
37 * giving you an opportunity to layout the content to match the new constraints.
38 * </li>
39 * <li>
40 * After every call to {@link #onLayout(PrintAttributes, PrintAttributes,
41 * CancellationSignal, LayoutResultCallback, Bundle)}, you <strong>may</strong> get
42 * a call to {@link #onWrite(PageRange[], ParcelFileDescriptor, CancellationSignal,
43 * WriteResultCallback)} asking you to write a PDF file with the content for
44 * specific pages.
45 * </li>
46 * <li>
47 * Finally, you will receive a call to {@link #onFinish()}. You can use this
48 * callback to release resources allocated in {@link #onStart()}.
49 * </li>
50 * </ul>
51 * <p>
52 * The {@link #onStart()} callback is always the first call you will receive and
53 * is useful for doing one time setup or resource allocation before printing. You
54 * will not receive a subsequent call here.
55 * </p>
56 * <p>
57 * The {@link #onLayout(PrintAttributes, PrintAttributes, CancellationSignal,
58 * LayoutResultCallback, Bundle)} callback requires that you layout the content
59 * based on the current {@link PrintAttributes}. The execution of this method is
60 * not considered completed until you invoke one of the methods on the passed in
61 * callback instance. Hence, you will not receive a subsequent call to any other
62 * method of this class until the execution of this method is complete by invoking
63 * one of the callback methods.
64 * </p>
65 * <p>
66 * The {@link #onWrite(PageRange[], ParcelFileDescriptor, CancellationSignal,
67 * WriteResultCallback)} requires that you render and write the content of some
68 * pages to the provided destination. The execution of this method is not
69 * considered complete until you invoke one of the methods on the passed in
70 * callback instance. Hence, you will not receive a subsequent call to any other
71 * method of this class until the execution of this method is complete by invoking
72 * one of the callback methods. You will never receive a sequence of one or more
73 * calls to this method without a previous call to {@link #onLayout(PrintAttributes,
74 * PrintAttributes, CancellationSignal, LayoutResultCallback, Bundle)}.
75 * </p>
76 * <p>
77 * The {@link #onFinish()} callback is always the last call you will receive and
78 * is useful for doing one time cleanup or resource deallocation after printing.
79 * You will not receive a subsequent call here.
80 * </p>
81 * </p>
82 * <h3>Implementation</h3>
83 * <p>
84 * The APIs defined in this class are designed to enable doing part or all
85 * of the work on an arbitrary thread. For example, if the printed content
86 * does not depend on the UI state, i.e. on what is shown on the screen, then
87 * you can offload the entire work on a dedicated thread, thus making your
88 * application interactive while the print work is being performed. Note that
89 * while your activity is covered by the system print UI and a user cannot
90 * interact with it, doing the printing work on the main application thread
91 * may affect the performance of your other application components as they
92 * are also executed on that thread.
93 * </p>
94 * <p>
95 * You can also do work on different threads, for example if you print UI
96 * content, you can handle {@link #onStart()} and {@link #onLayout(PrintAttributes,
97 * PrintAttributes, CancellationSignal, LayoutResultCallback, Bundle)} on
98 * the UI thread (assuming onStart initializes resources needed for layout).
99 * This will ensure that the UI does not change while you are laying out the
100 * printed content. Then you can handle {@link #onWrite(PageRange[], ParcelFileDescriptor,
101 * CancellationSignal, WriteResultCallback)} and {@link #onFinish()} on another
102 * thread. This will ensure that the main thread is busy for a minimal amount of
103 * time. Also this assumes that you will generate the printed content in
104 * {@link #onLayout(PrintAttributes, PrintAttributes, CancellationSignal,
105 * LayoutResultCallback, Bundle)} which is not mandatory. If you use multiple
106 * threads, you are responsible for proper synchronization.
107 * </p>
108 */
109public abstract class PrintDocumentAdapter {
110
111    /**
112     * Extra: mapped to a boolean value that is <code>true</code> if
113     * the current layout is for a print preview, <code>false</code> otherwise.
114     * This extra is provided in the {@link Bundle} argument of the {@link
115     * #onLayout(PrintAttributes, PrintAttributes, CancellationSignal,
116     * LayoutResultCallback, Bundle)} callback.
117     *
118     * @see #onLayout(PrintAttributes, PrintAttributes, CancellationSignal,
119     * LayoutResultCallback, Bundle)
120     */
121    public static final String EXTRA_PRINT_PREVIEW = "EXTRA_PRINT_PREVIEW";
122
123    /**
124     * Called when printing starts. You can use this callback to allocate
125     * resources. This method is invoked on the main thread.
126     */
127    public void onStart() {
128        /* do nothing - stub */
129    }
130
131    /**
132     * Called when the print attributes (page size, density, etc) changed
133     * giving you a chance to layout the content such that it matches the
134     * new constraints. This method is invoked on the main thread.
135     * <p>
136     * After you are done laying out, you <strong>must</strong> invoke: {@link
137     * LayoutResultCallback#onLayoutFinished(PrintDocumentInfo, boolean)} with
138     * the last argument <code>true</code> or <code>false</code> depending on
139     * whether the layout changed the content or not, respectively; or {@link
140     * LayoutResultCallback#onLayoutFailed(CharSequence)}, if an error occurred;
141     * or {@link LayoutResultCallback#onLayoutCancelled()} if layout was
142     * cancelled in a response to a cancellation request via the passed in
143     * {@link CancellationSignal}. Note that you <strong>must</strong> call one of
144     * the methods of the given callback for this method to be considered complete.
145     * </p>
146     * <p>
147     * <strong>Note:</strong> If the content is large and a layout will be
148     * performed, it is a good practice to schedule the work on a dedicated
149     * thread and register an observer in the provided {@link
150     * CancellationSignal} upon invocation of which you should stop the
151     * layout. The cancellation callback <strong>will not</strong> be made on
152     * the main thread.
153     * </p>
154     *
155     * @param oldAttributes The old print attributes.
156     * @param newAttributes The new print attributes.
157     * @param cancellationSignal Signal for observing cancel layout requests.
158     * @param callback Callback to inform the system for the layout result.
159     * @param extras Additional information about how to layout the content.
160     *
161     * @see LayoutResultCallback
162     * @see CancellationSignal
163     * @see #EXTRA_PRINT_PREVIEW
164     */
165    public abstract void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes,
166            CancellationSignal cancellationSignal, LayoutResultCallback callback,
167            Bundle extras);
168
169    /**
170     * Called when specific pages of the content should be written in the
171     * form of a PDF file to the given file descriptor. This method is invoked
172     * on the main thread.
173     *<p>
174     * After you are done writing, you should close the file descriptor and
175     * invoke {@link WriteResultCallback#onWriteFinished(PageRange[])}, if writing
176     * completed successfully; or {@link WriteResultCallback#onWriteFailed(
177     * CharSequence)}, if an error occurred; or {@link WriteResultCallback#onWriteCancelled()},
178     * if writing was cancelled in a response to a cancellation request via the passed
179     * in {@link CancellationSignal}. Note that you <strong>must</strong> call one of
180     * the methods of the given callback for this method to be considered complete.
181     * </p>
182     * <p>
183     * <strong>Note:</strong> If the printed content is large, it is a good
184     * practice to schedule writing it on a dedicated thread and register an
185     * observer in the provided {@link CancellationSignal} upon invocation of
186     * which you should stop writing. The cancellation callback will not be
187     * made on the main thread.
188     * </p>
189     *
190     * @param pages The pages whose content to print - non-overlapping in ascending order.
191     * @param destination The destination file descriptor to which to write.
192     * @param cancellationSignal Signal for observing cancel writing requests.
193     * @param callback Callback to inform the system for the write result.
194     *
195     * @see WriteResultCallback
196     * @see CancellationSignal
197     */
198    public abstract void onWrite(PageRange[] pages, ParcelFileDescriptor destination,
199            CancellationSignal cancellationSignal, WriteResultCallback callback);
200
201    /**
202     * Called when printing finishes. You can use this callback to release
203     * resources acquired in {@link #onStart()}. This method is invoked on
204     * the main thread.
205     */
206    public void onFinish() {
207        /* do nothing - stub */
208    }
209
210    /**
211     * Base class for implementing a callback for the result of {@link
212     * PrintDocumentAdapter#onWrite(PageRange[], ParcelFileDescriptor, CancellationSignal,
213     * WriteResultCallback)}.
214     */
215    public static abstract class WriteResultCallback {
216
217        /**
218         * @hide
219         */
220        public WriteResultCallback() {
221            /* do nothing - hide constructor */
222        }
223
224        /**
225         * Notifies that all the data was written.
226         *
227         * @param pages The pages that were written. Cannot be <code>null</code>
228         * or empty.
229         */
230        public void onWriteFinished(PageRange[] pages) {
231            /* do nothing - stub */
232        }
233
234        /**
235         * Notifies that an error occurred while writing the data.
236         *
237         * @param error The <strong>localized</strong> error message.
238         * shown to the user. May be <code>null</code> if error is unknown.
239         */
240        public void onWriteFailed(CharSequence error) {
241            /* do nothing - stub */
242        }
243
244        /**
245         * Notifies that write was cancelled as a result of a cancellation request.
246         */
247        public void onWriteCancelled() {
248            /* do nothing - stub */
249        }
250    }
251
252    /**
253     * Base class for implementing a callback for the result of {@link
254     * PrintDocumentAdapter#onLayout(PrintAttributes, PrintAttributes,
255     * CancellationSignal, LayoutResultCallback, Bundle)}.
256     */
257    public static abstract class LayoutResultCallback {
258
259        /**
260         * @hide
261         */
262        public LayoutResultCallback() {
263            /* do nothing - hide constructor */
264        }
265
266        /**
267         * Notifies that the layout finished and whether the content changed.
268         *
269         * @param info An info object describing the document. Cannot be <code>null</code>.
270         * @param changed Whether the layout changed.
271         *
272         * @see PrintDocumentInfo
273         */
274        public void onLayoutFinished(PrintDocumentInfo info, boolean changed) {
275            /* do nothing - stub */
276        }
277
278        /**
279         * Notifies that an error occurred while laying out the document.
280         *
281         * @param error The <strong>localized</strong> error message.
282         * shown to the user. May be <code>null</code> if error is unknown.
283         */
284        public void onLayoutFailed(CharSequence error) {
285            /* do nothing - stub */
286        }
287
288        /**
289         * Notifies that layout was cancelled as a result of a cancellation request.
290         */
291        public void onLayoutCancelled() {
292            /* do nothing - stub */
293        }
294    }
295}
296