PrintFileDocumentAdapter.java revision a00271533f639c8ed36429c663889ac9f654bc72
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 194b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.os.AsyncTask; 204b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.os.CancellationSignal; 214b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.os.CancellationSignal.OnCancelListener; 224b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.util.Log; 234b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 244b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport libcore.io.IoUtils; 254b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 264b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport java.io.File; 274b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport java.io.FileDescriptor; 284b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport java.io.FileInputStream; 294b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport java.io.FileOutputStream; 304b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport java.io.IOException; 314b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport java.io.InputStream; 324b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport java.io.OutputStream; 334b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport java.util.ArrayList; 344b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport java.util.List; 354b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 364b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov/** 374b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * Adapter for printing files. 384b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov */ 39a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovfinal class FileDocumentAdapter extends PrintDocumentAdapter { 404b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 41a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private static final String LOG_TAG = "FileDocumentAdapter"; 424b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 434b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov private final File mFile; 444b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 454b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov private WriteFileAsyncTask mWriteFileAsyncTask; 464b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 47a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public FileDocumentAdapter(File file) { 484b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov if (file == null) { 494b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov throw new IllegalArgumentException("File cannot be null!"); 504b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 514b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov mFile = file; 524b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 534b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 544b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov @Override 55a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, 56a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov CancellationSignal cancellationSignal, LayoutResultCallback callback) { 57a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov // TODO: When we have a PDF rendering library we should query the page count. 58a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov PrintDocumentInfo info = new PrintDocumentInfo.Builder() 59a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov .setPageCount(PrintDocumentInfo.PAGE_COUNT_UNKNOWN).create(); 60a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov callback.onLayoutFinished(info, false); 61a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 62a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 63a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 64a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onWrite(List<PageRange> pages, FileDescriptor destination, 65a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov CancellationSignal cancellationSignal, WriteResultCallback callback) { 664b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov mWriteFileAsyncTask = new WriteFileAsyncTask(mFile, destination, cancellationSignal, 67fd90651cfcc7e2b75254666fd6861038b72fb4acSvetoslav callback); 684b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov mWriteFileAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, 694b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov (Void[]) null); 704b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 714b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 724b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 734b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov private static final class WriteFileAsyncTask extends AsyncTask<Void, Void, Void> { 744b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 754b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov private final File mSource; 764b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 774b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov private final FileDescriptor mDestination; 784b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 79a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final WriteResultCallback mResultCallback; 804b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 814b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov private final CancellationSignal mCancellationSignal; 824b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 834b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov public WriteFileAsyncTask(File source, FileDescriptor destination, 84a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov CancellationSignal cancellationSignal, WriteResultCallback callback) { 854b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov mSource = source; 864b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov mDestination = destination; 87fd90651cfcc7e2b75254666fd6861038b72fb4acSvetoslav mResultCallback = callback; 884b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov mCancellationSignal = cancellationSignal; 894b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov mCancellationSignal.setOnCancelListener(new OnCancelListener() { 904b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov @Override 914b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov public void onCancel() { 924b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov cancel(true); 934b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 944b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov }); 954b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 964b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 974b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov @Override 984b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov protected Void doInBackground(Void... params) { 994b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov InputStream in = null; 1004b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov OutputStream out = new FileOutputStream(mDestination); 1014b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov final byte[] buffer = new byte[8192]; 1024b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov try { 1034b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov in = new FileInputStream(mSource); 1044b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov while (true) { 1054b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov final int readByteCount = in.read(buffer); 1064b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov if (readByteCount < 0) { 1074b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov break; 1084b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 1094b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov out.write(buffer, 0, readByteCount); 1104b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 1114b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } catch (IOException ioe) { 1124b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov Log.e(LOG_TAG, "Error writing data!", ioe); 1134b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } finally { 1144b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov IoUtils.closeQuietly(in); 1154b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov IoUtils.closeQuietly(out); 1164b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov if (!isCancelled()) { 1174b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov List<PageRange> pages = new ArrayList<PageRange>(); 1184b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov pages.add(PageRange.ALL_PAGES); 119a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mResultCallback.onWriteFinished(pages); 1204b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } else { 121a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mResultCallback.onWriteFailed("Cancelled"); 1224b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 1234b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 1244b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov return null; 1254b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 1264b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 1274b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov} 1284b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 129