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 17 package android.print; 18 19 import android.content.Context; 20 import android.os.AsyncTask; 21 import android.os.Bundle; 22 import android.os.CancellationSignal; 23 import android.os.CancellationSignal.OnCancelListener; 24 import android.os.FileUtils; 25 import android.os.OperationCanceledException; 26 import android.os.ParcelFileDescriptor; 27 import android.util.Log; 28 29 import com.android.internal.R; 30 31 import libcore.io.IoUtils; 32 33 import java.io.File; 34 import java.io.FileInputStream; 35 import java.io.FileOutputStream; 36 import java.io.IOException; 37 import java.io.InputStream; 38 import java.io.OutputStream; 39 40 /** 41 * Adapter for printing PDF files. This class could be useful if you 42 * want to print a file and intercept when the system is ready 43 * spooling the data, so you can delete the file if it is a 44 * temporary one. To achieve this one must override {@link #onFinish()} 45 * and delete the file yourself. 46 * 47 * @hide 48 */ 49 public class PrintFileDocumentAdapter extends PrintDocumentAdapter { 50 51 private static final String LOG_TAG = "PrintedFileDocAdapter"; 52 53 private final Context mContext; 54 55 private final File mFile; 56 57 private final PrintDocumentInfo mDocumentInfo; 58 59 private WriteFileAsyncTask mWriteFileAsyncTask; 60 61 /** 62 * Constructor. 63 * 64 * @param context Context for accessing resources. 65 * @param file The PDF file to print. 66 * @param documentInfo The information about the printed file. 67 */ 68 public PrintFileDocumentAdapter(Context context, File file, 69 PrintDocumentInfo documentInfo) { 70 if (file == null) { 71 throw new IllegalArgumentException("File cannot be null!"); 72 } 73 if (documentInfo == null) { 74 throw new IllegalArgumentException("documentInfo cannot be null!"); 75 } 76 mContext = context; 77 mFile = file; 78 mDocumentInfo = documentInfo; 79 } 80 81 @Override 82 public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, 83 CancellationSignal cancellationSignal, LayoutResultCallback callback, 84 Bundle metadata) { 85 callback.onLayoutFinished(mDocumentInfo, false); 86 } 87 88 @Override 89 public void onWrite(PageRange[] pages, ParcelFileDescriptor destination, 90 CancellationSignal cancellationSignal, WriteResultCallback callback) { 91 mWriteFileAsyncTask = new WriteFileAsyncTask(destination, cancellationSignal, callback); 92 mWriteFileAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, 93 (Void[]) null); 94 } 95 96 private final class WriteFileAsyncTask extends AsyncTask<Void, Void, Void> { 97 98 private final ParcelFileDescriptor mDestination; 99 100 private final WriteResultCallback mResultCallback; 101 102 private final CancellationSignal mCancellationSignal; 103 104 public WriteFileAsyncTask(ParcelFileDescriptor destination, 105 CancellationSignal cancellationSignal, WriteResultCallback callback) { 106 mDestination = destination; 107 mResultCallback = callback; 108 mCancellationSignal = cancellationSignal; 109 mCancellationSignal.setOnCancelListener(new OnCancelListener() { 110 @Override 111 public void onCancel() { 112 cancel(true); 113 } 114 }); 115 } 116 117 @Override 118 protected Void doInBackground(Void... params) { 119 try (InputStream in = new FileInputStream(mFile); 120 OutputStream out = new FileOutputStream(mDestination.getFileDescriptor())) { 121 FileUtils.copy(in, out, mCancellationSignal, null, null); 122 } catch (OperationCanceledException e) { 123 // Ignored; already handled below 124 } catch (IOException e) { 125 Log.e(LOG_TAG, "Error writing data!", e); 126 mResultCallback.onWriteFailed(mContext.getString( 127 R.string.write_fail_reason_cannot_write)); 128 } 129 return null; 130 } 131 132 @Override 133 protected void onPostExecute(Void result) { 134 mResultCallback.onWriteFinished(new PageRange[] {PageRange.ALL_PAGES}); 135 } 136 137 @Override 138 protected void onCancelled(Void result) { 139 mResultCallback.onWriteFailed(mContext.getString( 140 R.string.write_fail_reason_cancelled)); 141 } 142 } 143 } 144 145