PrintDocumentAdapter.java revision 19fba5d34a444ce145ab0d3a12c578d9d5d3f38c
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 23import java.util.List; 24 25/** 26 * Base class that provides the content of a document to be printed. 27 * 28 * <h3>Lifecycle</h3> 29 * <p> 30 * <ul> 31 * <li> 32 * Initially, you will receive a call to {@link #onStart()}. This callback 33 * can be used to allocate resources. 34 * </li> 35 * <li> 36 * Next, you will get one or more calls to {@link #onLayout(PrintAttributes, 37 * PrintAttributes, CancellationSignal, LayoutResultCallback, Bundle)} to 38 * inform you that the print attributes (page size, density, etc) changed 39 * giving you an opportunity to layout the content to match the new constraints. 40 * </li> 41 * <li> 42 * After every call to {@link #onLayout(PrintAttributes, PrintAttributes, 43 * CancellationSignal, LayoutResultCallback, Bundle)}, you may get a call to 44 * {@link #onWrite(PageRange[], ParcelFileDescriptor, CancellationSignal, WriteResultCallback)} 45 * asking you to write a PDF file with the content for specific pages. 46 * </li> 47 * <li> 48 * Finally, you will receive a call to {@link #onFinish()}. You can use this 49 * callback to release resources allocated in {@link #onStart()}. 50 * </li> 51 * </ul> 52 * </p> 53 * <h3>Implementation</h3> 54 * <p> 55 * The APIs defined in this class are designed to enable doing part or all 56 * of the work on an arbitrary thread. For example, if the printed content 57 * does not depend on the UI state, i.e. on what is shown on the screen, then 58 * you can offload the entire work on a dedicated thread, thus making your 59 * application interactive while the print work is being performed. 60 * </p> 61 * <p> 62 * You can also do work on different threads, for example if you print UI 63 * content, you can handle {@link #onStart()} and {@link #onLayout(PrintAttributes, 64 * PrintAttributes, CancellationSignal, LayoutResultCallback, Bundle)} on 65 * the UI thread (assuming onStart initializes resources needed for layout). 66 * This will ensure that the UI does not change while you are laying out the 67 * printed content. Then you can handle {@link #onWrite(PageRange[], ParcelFileDescriptor, 68 * CancellationSignal, WriteResultCallback)} and {@link #onFinish()} on another 69 * thread. This will ensure that the UI is frozen for the minimal amount of 70 * time. Also this assumes that you will generate the printed content in 71 * {@link #onLayout(PrintAttributes, PrintAttributes, CancellationSignal, 72 * LayoutResultCallback, Bundle)} which is not mandatory. If you use multiple 73 * threads, you are responsible for proper synchronization. 74 * </p> 75 */ 76public abstract class PrintDocumentAdapter { 77 78 /** 79 * Meta-data key: mapped to a boolean value that is <code>true</code> if 80 * the current layout is for a print preview, <code>false</code> otherwise. 81 */ 82 public static final String METADATA_KEY_PRINT_PREVIEW = "KEY_METADATA_PRINT_PREVIEW"; 83 84 /** 85 * Called when printing starts. You can use this callback to allocate 86 * resources. This method is invoked on the main thread. 87 */ 88 public void onStart() { 89 /* do nothing - stub */ 90 } 91 92 /** 93 * Called when the print attributes (page size, density, etc) changed 94 * giving you a chance to layout the content such that it matches the 95 * new constraints. This method is invoked on the main thread. 96 * <p> 97 * After you are done laying out, you <strong>must</strong> invoke: {@link 98 * LayoutResultCallback#onLayoutFinished(PrintDocumentInfo, boolean)} with 99 * the last argument <code>true</code> or <code>false</code> depending on 100 * whether the layout changed the content or not, respectively; and {@link 101 * LayoutResultCallback#onLayoutFailed(CharSequence)}, if an error occurred. 102 * Note that you must call one of the methods of the given callback. 103 * </p> 104 * <p> 105 * When doing a layout you may satisfy some of the constraints in the print 106 * attributes such as applying the appropriate fitting, emitting content in the 107 * requested orientation, using the specified margins, generating content with 108 * the desired color mode, producing output with the given media size. Ideally, 109 * you will satisfy all of these constraints. It is important that if you 110 * satisfy a given constraint, you update the {@link PrintDocumentInfo} that 111 * is returned in the given {@link LayoutResultCallback}. This way the printer 112 * will have more accurate information about the content, thus producing a 113 * better output. For example, assume that your application is printing 114 * an image and the print attributes request landscape and fitting mode scale 115 * to fill. The result of this operation should be the entire media is filled 116 * and the content is rotated ninety degrees. In this case it is beneficial 117 * you do the rotation and select a higher resolution image to utilize 118 * the wider media (the height is now the width), rather to use a lower 119 * resolution image that is later stretched by the printer. If you applied 120 * the rotation you have to update the returned print document info to 121 * reflect that the content is already in landscape by calling 122 * {@link PrintDocumentInfo.Builder#setOrientation(int)} with {@link 123 * PrintAttributes#ORIENTATION_LANDSCAPE}. In this case the printer does not 124 * have to rotate the content. 125 * </p> 126 * <p> 127 * <strong>Note:</strong> If the content is large and a layout will be 128 * performed, it is a good practice to schedule the work on a dedicated 129 * thread and register an observer in the provided {@link 130 * CancellationSignal} upon invocation of which you should stop the 131 * layout. The cancellation callback will not be made on the main 132 * thread. 133 * </p> 134 * 135 * @param oldAttributes The old print attributes. 136 * @param newAttributes The new print attributes. 137 * @param cancellationSignal Signal for observing cancel layout requests. 138 * @param callback Callback to inform the system for the layout result. 139 * @param metadata Additional information about how layout the content. 140 * 141 * @see LayoutResultCallback 142 * @see CancellationSignal 143 * @see #METADATA_KEY_PRINT_PREVIEW 144 */ 145 public abstract void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, 146 CancellationSignal cancellationSignal, LayoutResultCallback callback, 147 Bundle metadata); 148 149 /** 150 * Called when specific pages of the content should be written in the 151 * form of a PDF file to the given file descriptor. This method is invoked 152 * on the main thread. 153 *<p> 154 * After you are done writing, you should close the file descriptor and 155 * invoke {@link WriteResultCallback #onWriteFinished(PageRange[]), if writing 156 * completed successfully; or {@link WriteResultCallback#onWriteFailed( 157 * CharSequence)}, if an error occurred. Note that you must call one of 158 * the methods of the given callback. 159 * </p> 160 * <p> 161 * <strong>Note:</strong> If the printed content is large, it is a good 162 * practice to schedule writing it on a dedicated thread and register an 163 * observer in the provided {@link CancellationSignal} upon invocation of 164 * which you should stop writing. The cancellation callback will not be 165 * made on the main thread. 166 * </p> 167 * 168 * @param pages The pages whose content to print - non-overlapping in ascending order. 169 * @param destination The destination file descriptor to which to write. 170 * @param cancellationSignal Signal for observing cancel writing requests. 171 * @param callback Callback to inform the system for the write result. 172 * 173 * @see WriteResultCallback 174 * @see CancellationSignal 175 */ 176 public abstract void onWrite(PageRange[] pages, ParcelFileDescriptor destination, 177 CancellationSignal cancellationSignal, WriteResultCallback callback); 178 179 /** 180 * Called when printing finishes. You can use this callback to release 181 * resources acquired in {@link #onStart()}. This method is invoked on 182 * the main thread. 183 */ 184 public void onFinish() { 185 /* do nothing - stub */ 186 } 187 188 /** 189 * Base class for implementing a callback for the result of {@link 190 * PrintDocumentAdapter#onWrite(PageRange[], ParcelFileDescriptor, CancellationSignal, 191 * WriteResultCallback)}. 192 */ 193 public static abstract class WriteResultCallback { 194 195 /** 196 * @hide 197 */ 198 public WriteResultCallback() { 199 /* do nothing - hide constructor */ 200 } 201 202 /** 203 * Notifies that all the data was written. 204 * 205 * @param pages The pages that were written. Cannot be null or empty. 206 */ 207 public void onWriteFinished(PageRange[] pages) { 208 /* do nothing - stub */ 209 } 210 211 /** 212 * Notifies that an error occurred while writing the data. 213 * 214 * @param error Error message. May be null if error is unknown. 215 */ 216 public void onWriteFailed(CharSequence error) { 217 /* do nothing - stub */ 218 } 219 220 /** 221 * Notifies that write was cancelled as a result of a cancellation request. 222 */ 223 public void onWriteCancelled() { 224 /* do nothing - stub */ 225 } 226 } 227 228 /** 229 * Base class for implementing a callback for the result of {@link 230 * PrintDocumentAdapter#onLayout(PrintAttributes, PrintAttributes, 231 * CancellationSignal, LayoutResultCallback, Bundle)}. 232 */ 233 public static abstract class LayoutResultCallback { 234 235 /** 236 * @hide 237 */ 238 public LayoutResultCallback() { 239 /* do nothing - hide constructor */ 240 } 241 242 /** 243 * Notifies that the layout finished and whether the content changed. 244 * 245 * @param info An info object describing the document. Cannot be null. 246 * @param changed Whether the layout changed. 247 * 248 * @see PrintDocumentInfo 249 */ 250 public void onLayoutFinished(PrintDocumentInfo info, boolean changed) { 251 /* do nothing - stub */ 252 } 253 254 /** 255 * Notifies that an error occurred while laying out the document. 256 * 257 * @param error Error message. May be null if error is unknown. 258 */ 259 public void onLayoutFailed(CharSequence error) { 260 /* do nothing - stub */ 261 } 262 263 /** 264 * Notifies that layout was cancelled as a result of a cancellation request. 265 */ 266 public void onLayoutCancelled() { 267 /* do nothing - stub */ 268 } 269 } 270} 271