PrintDocumentAdapter.java revision d26d4898fcc9b78f4b66118895c375384098205e
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 off load 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 * </p> 103 * <p> 104 * When doing a layout you may satisfy some of the constraints in the print 105 * attributes such as applying the appropriate fitting, emitting content in the 106 * requested orientation, using the specified margins, generating content with 107 * the desired color mode, producing output with the given media size. Ideally, 108 * you will satisfy all of these constraints. It is important that if you 109 * satisfy a given constraint, you update the {@link PrintDocumentInfo} that 110 * is returned in the given {@link LayoutResultCallback}. This way the printer 111 * will have more accurate information about the content, thus producing a 112 * better output. For example, assume that your application is printing 113 * an image and the print attributes request landscape and fitting mode scale 114 * to fill. The result of this operation should be the entire media is filled 115 * and the content is rotated ninety degrees. In this case it is beneficial 116 * you do the rotation and select a higher resolution image to utilize 117 * the wider media (the height is now the width), rather to use a lower 118 * resolution image that is later stretched by the printer. If you applied 119 * the rotation you have to update the returned print document info to 120 * reflect that the content is already in landscape by calling 121 * {@link PrintDocumentInfo.Builder#setOrientation(int)} with {@link 122 * PrintAttributes#ORIENTATION_LANDSCAPE}. In this case the printer does not 123 * have to rotate the content. 124 * </p> 125 * <p> 126 * <strong>Note:</strong> If the content is large and a layout will be 127 * performed, it is a good practice to schedule the work on a dedicated 128 * thread and register an observer in the provided {@link 129 * CancellationSignal} upon invocation of which you should stop the 130 * layout. The cancellation callback will not be made on the main 131 * thread. 132 * </p> 133 * 134 * @param oldAttributes The old print attributes. 135 * @param newAttributes The new print attributes. 136 * @param cancellationSignal Signal for observing cancel layout requests. 137 * @param callback Callback to inform the system for the layout result. 138 * @param metadata Additional information about how layout the content. 139 * 140 * @see LayoutResultCallback 141 * @see CancellationSignal 142 * @see #METADATA_KEY_PRINT_PREVIEW 143 */ 144 public abstract void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, 145 CancellationSignal cancellationSignal, LayoutResultCallback callback, 146 Bundle metadata); 147 148 /** 149 * Called when specific pages of the content should be written in the 150 * from of a PDF file to the given file descriptor. This method is invoked 151 * on the main thread. 152 *<p> 153 * After you are done writing, you should close the file descriptor and 154 * invoke {@link WriteResultCallback #onWriteFinished(List)}, if writing 155 * completed successfully; or {@link WriteResultCallback#onWriteFailed( 156 * CharSequence)}, if an error occurred. 157 * </p> 158 * <p> 159 * <strong>Note:</strong> If the printed content is large, it is a good 160 * practice to schedule writing it on a dedicated thread and register an 161 * observer in the provided {@link CancellationSignal} upon invocation of 162 * which you should stop writing. The cancellation callback will not be 163 * made on the main thread. 164 * </p> 165 * 166 * @param pages The pages whose content to print - non-overlapping in ascending order. 167 * @param destination The destination file descriptor to which to write. 168 * @param cancellationSignal Signal for observing cancel writing requests. 169 * @param callback Callback to inform the system for the write result. 170 * 171 * @see WriteResultCallback 172 * @see CancellationSignal 173 */ 174 public abstract void onWrite(PageRange[] pages, ParcelFileDescriptor destination, 175 CancellationSignal cancellationSignal, WriteResultCallback callback); 176 177 /** 178 * Called when printing finishes. You can use this callback to release 179 * resources acquired in {@link #onStart()}. This method is invoked on 180 * the main thread. 181 */ 182 public void onFinish() { 183 /* do nothing - stub */ 184 } 185 186 /** 187 * Base class for implementing a callback for the result of {@link 188 * PrintDocumentAdapter#onWrite(PageRange[], ParcelFileDescriptor, CancellationSignal, 189 * WriteResultCallback)}. 190 */ 191 public static abstract class WriteResultCallback { 192 193 /** 194 * @hide 195 */ 196 public WriteResultCallback() { 197 /* do nothing - hide constructor */ 198 } 199 200 /** 201 * Notifies that all the data was written. 202 * 203 * @param pages The pages that were written. Cannot be null or empty. 204 */ 205 public void onWriteFinished(PageRange[] pages) { 206 /* do nothing - stub */ 207 } 208 209 /** 210 * Notifies that an error occurred while writing the data. 211 * 212 * @param error Error message. May be null if error is unknown. 213 */ 214 public void onWriteFailed(CharSequence error) { 215 /* do nothing - stub */ 216 } 217 218 /** 219 * Notifies that write was cancelled as a result of a cancellation request. 220 */ 221 public void onWriteCancelled() { 222 /* do nothing - stub */ 223 } 224 } 225 226 /** 227 * Base class for implementing a callback for the result of {@link 228 * PrintDocumentAdapter#onLayout(PrintAttributes, PrintAttributes, 229 * CancellationSignal, LayoutResultCallback, Bundle)}. 230 */ 231 public static abstract class LayoutResultCallback { 232 233 /** 234 * @hide 235 */ 236 public LayoutResultCallback() { 237 /* do nothing - hide constructor */ 238 } 239 240 /** 241 * Notifies that the layout finished and whether the content changed. 242 * 243 * @param info An info object describing the document. Cannot be null. 244 * @param changed Whether the layout changed. 245 * 246 * @see PrintDocumentInfo 247 */ 248 public void onLayoutFinished(PrintDocumentInfo info, boolean changed) { 249 /* do nothing - stub */ 250 } 251 252 /** 253 * Notifies that an error occurred while laying out the document. 254 * 255 * @param error Error message. May be null if error is unknown. 256 */ 257 public void onLayoutFailed(CharSequence error) { 258 /* do nothing - stub */ 259 } 260 261 /** 262 * Notifies that layout was cancelled as a result of a cancellation request. 263 */ 264 public void onLayoutCancelled() { 265 /* do nothing - stub */ 266 } 267 } 268} 269