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