PrintFileDocumentAdapter.java revision d26d4898fcc9b78f4b66118895c375384098205e
14b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov/* 24b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * Copyright (C) 2013 The Android Open Source Project 34b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * 44b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * Licensed under the Apache License, Version 2.0 (the "License"); 54b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * you may not use this file except in compliance with the License. 64b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * You may obtain a copy of the License at 74b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * 84b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * http://www.apache.org/licenses/LICENSE-2.0 94b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * 104b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * Unless required by applicable law or agreed to in writing, software 114b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * distributed under the License is distributed on an "AS IS" BASIS, 124b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * See the License for the specific language governing permissions and 144b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * limitations under the License. 154b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov */ 164b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 174b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovpackage android.print; 184b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 1917b7f6e6d4ec9f5e9597bfd283f1c017b6c66275Svetoslavimport android.content.Context; 204b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.os.AsyncTask; 216283608e0bd40548742839f5a8b02f7e5c9c5c7cSvetoslavimport android.os.Bundle; 224b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.os.CancellationSignal; 234b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.os.CancellationSignal.OnCancelListener; 24d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganovimport android.os.ParcelFileDescriptor; 254b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.util.Log; 264b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 2717b7f6e6d4ec9f5e9597bfd283f1c017b6c66275Svetoslavimport com.android.internal.R; 2817b7f6e6d4ec9f5e9597bfd283f1c017b6c66275Svetoslav 294b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport libcore.io.IoUtils; 304b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 314b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport java.io.File; 324b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport java.io.FileInputStream; 334b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport java.io.FileOutputStream; 344b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport java.io.IOException; 354b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport java.io.InputStream; 364b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport java.io.OutputStream; 374b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 384b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov/** 39798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * Adapter for printing files. This class could be useful if you 40798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * want to print a file and intercept when the system is ready 41798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * spooling the data, so you can deleted the file if it is a 42798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * temporary one. 434b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov */ 449abf735387329758ca310acad3baa70eee1dba42Svetoslavpublic class PrintFileDocumentAdapter extends PrintDocumentAdapter { 454b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 46798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov private static final String LOG_TAG = "PrintedFileDocumentAdapter"; 474b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 4817b7f6e6d4ec9f5e9597bfd283f1c017b6c66275Svetoslav private final Context mContext; 4917b7f6e6d4ec9f5e9597bfd283f1c017b6c66275Svetoslav 504b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov private final File mFile; 514b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 52798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov private final PrintDocumentInfo mDocumentInfo; 53798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov 544b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov private WriteFileAsyncTask mWriteFileAsyncTask; 554b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 56798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov /** 57798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * Constructor. 58798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * 59798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * @param context Context for accessing resources. 60798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * @param file The file to print. 61798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * @param documentInfo The information about the printed file. 62798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov */ 63798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov public PrintFileDocumentAdapter(Context context, File file, 64798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov PrintDocumentInfo documentInfo) { 654b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov if (file == null) { 664b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov throw new IllegalArgumentException("File cannot be null!"); 674b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 68798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov if (documentInfo == null) { 69798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov throw new IllegalArgumentException("documentInfo cannot be null!"); 70798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov } 7117b7f6e6d4ec9f5e9597bfd283f1c017b6c66275Svetoslav mContext = context; 724b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov mFile = file; 73798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov mDocumentInfo = documentInfo; 744b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 754b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 764b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov @Override 77a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, 786283608e0bd40548742839f5a8b02f7e5c9c5c7cSvetoslav CancellationSignal cancellationSignal, LayoutResultCallback callback, 796283608e0bd40548742839f5a8b02f7e5c9c5c7cSvetoslav Bundle metadata) { 80798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov callback.onLayoutFinished(mDocumentInfo, false); 81a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 82a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 83a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 84d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov public void onWrite(PageRange[] pages, ParcelFileDescriptor destination, 85a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov CancellationSignal cancellationSignal, WriteResultCallback callback) { 8617b7f6e6d4ec9f5e9597bfd283f1c017b6c66275Svetoslav mWriteFileAsyncTask = new WriteFileAsyncTask(destination, cancellationSignal, callback); 874b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov mWriteFileAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, 884b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov (Void[]) null); 894b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 904b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 9117b7f6e6d4ec9f5e9597bfd283f1c017b6c66275Svetoslav private final class WriteFileAsyncTask extends AsyncTask<Void, Void, Void> { 924b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 93d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov private final ParcelFileDescriptor mDestination; 944b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 95a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final WriteResultCallback mResultCallback; 964b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 974b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov private final CancellationSignal mCancellationSignal; 984b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 99d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov public WriteFileAsyncTask(ParcelFileDescriptor destination, 100a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov CancellationSignal cancellationSignal, WriteResultCallback callback) { 1014b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov mDestination = destination; 102fd90651cfcc7e2b75254666fd6861038b72fb4acSvetoslav mResultCallback = callback; 10317b7f6e6d4ec9f5e9597bfd283f1c017b6c66275Svetoslav mCancellationSignal = cancellationSignal; 1044b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov mCancellationSignal.setOnCancelListener(new OnCancelListener() { 1054b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov @Override 1064b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov public void onCancel() { 1074b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov cancel(true); 1084b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 1094b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov }); 1104b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 1114b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 1124b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov @Override 1134b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov protected Void doInBackground(Void... params) { 1144b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov InputStream in = null; 115d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov OutputStream out = new FileOutputStream(mDestination.getFileDescriptor()); 1164b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov final byte[] buffer = new byte[8192]; 1174b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov try { 11817b7f6e6d4ec9f5e9597bfd283f1c017b6c66275Svetoslav in = new FileInputStream(mFile); 1194b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov while (true) { 12017b7f6e6d4ec9f5e9597bfd283f1c017b6c66275Svetoslav if (isCancelled()) { 12117b7f6e6d4ec9f5e9597bfd283f1c017b6c66275Svetoslav break; 12217b7f6e6d4ec9f5e9597bfd283f1c017b6c66275Svetoslav } 1234b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov final int readByteCount = in.read(buffer); 1244b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov if (readByteCount < 0) { 1254b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov break; 1264b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 1274b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov out.write(buffer, 0, readByteCount); 1284b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 1294b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } catch (IOException ioe) { 13017b7f6e6d4ec9f5e9597bfd283f1c017b6c66275Svetoslav Log.e(LOG_TAG, "Error writing data!", ioe); 13117b7f6e6d4ec9f5e9597bfd283f1c017b6c66275Svetoslav mResultCallback.onWriteFailed(mContext.getString( 13217b7f6e6d4ec9f5e9597bfd283f1c017b6c66275Svetoslav R.string.write_fail_reason_cannot_write)); 1334b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } finally { 1344b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov IoUtils.closeQuietly(in); 1354b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov IoUtils.closeQuietly(out); 1364b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 1374b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov return null; 1384b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 13917b7f6e6d4ec9f5e9597bfd283f1c017b6c66275Svetoslav 14017b7f6e6d4ec9f5e9597bfd283f1c017b6c66275Svetoslav @Override 14117b7f6e6d4ec9f5e9597bfd283f1c017b6c66275Svetoslav protected void onPostExecute(Void result) { 14285b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mResultCallback.onWriteFinished(new PageRange[] {PageRange.ALL_PAGES}); 14317b7f6e6d4ec9f5e9597bfd283f1c017b6c66275Svetoslav } 14417b7f6e6d4ec9f5e9597bfd283f1c017b6c66275Svetoslav 14517b7f6e6d4ec9f5e9597bfd283f1c017b6c66275Svetoslav @Override 14617b7f6e6d4ec9f5e9597bfd283f1c017b6c66275Svetoslav protected void onCancelled(Void result) { 14717b7f6e6d4ec9f5e9597bfd283f1c017b6c66275Svetoslav mResultCallback.onWriteFailed(mContext.getString( 14817b7f6e6d4ec9f5e9597bfd283f1c017b6c66275Svetoslav R.string.write_fail_reason_cancelled)); 14917b7f6e6d4ec9f5e9597bfd283f1c017b6c66275Svetoslav } 1504b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 1514b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov} 1524b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 153