From 5ef522bc19cc9fc1af48cccd2865744228c5ec02 Mon Sep 17 00:00:00 2001 From: Svetoslav Date: Wed, 23 Jul 2014 20:15:09 -0700 Subject: [PATCH] Handle wrong file format when printing. PDF is the only format suppored for printing but a buggy app can write content in another format which was crashing the print spooler. Now we are generating an error instead of crashing. bug:16487161 Change-Id: Ic59d2ac6d57213f4e8f364659d8dc7df2140e61d --- .../model/PageContentRepository.java | 26 ++++++++++++++---- .../android/printspooler/ui/PageAdapter.java | 27 +++++++++++-------- .../printspooler/ui/PrintActivity.java | 27 ++++++++++++------- 3 files changed, 54 insertions(+), 26 deletions(-) diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java b/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java index 3678cf269f507..c3ddad991343a 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java +++ b/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java @@ -76,8 +76,13 @@ public final class PageContentRepository { public void onPageContentAvailable(BitmapDrawable content); } - public PageContentRepository(Context context) { - mRenderer = new AsyncRenderer(context); + public interface OnMalformedPdfFileListener { + public void onMalformedPdfFile(); + } + + public PageContentRepository(Context context, + OnMalformedPdfFileListener malformedPdfFileListener) { + mRenderer = new AsyncRenderer(context, malformedPdfFileListener); mState = STATE_CLOSED; if (DEBUG) { Log.i(LOG_TAG, "STATE_CLOSED"); @@ -440,19 +445,24 @@ public final class PageContentRepository { } private static class AsyncRenderer { + private static final int MALFORMED_PDF_FILE_ERROR = -2; + private final Context mContext; private final PageContentLruCache mPageContentCache; private final ArrayMap mPageToRenderTaskMap = new ArrayMap<>(); + private final OnMalformedPdfFileListener mOnMalformedPdfFileListener; + private int mPageCount = PrintDocumentInfo.PAGE_COUNT_UNKNOWN; // Accessed only by the executor thread. private PdfRenderer mRenderer; - public AsyncRenderer(Context context) { + public AsyncRenderer(Context context, OnMalformedPdfFileListener malformedPdfFileListener) { mContext = context; + mOnMalformedPdfFileListener = malformedPdfFileListener; ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); @@ -474,13 +484,19 @@ public final class PageContentRepository { mRenderer = new PdfRenderer(source); return mRenderer.getPageCount(); } catch (IOException ioe) { - throw new IllegalStateException("Cannot open PDF document"); + Log.e(LOG_TAG, "Cannot open PDF document"); + return MALFORMED_PDF_FILE_ERROR; } } @Override public void onPostExecute(Integer pageCount) { - mPageCount = pageCount; + if (pageCount == MALFORMED_PDF_FILE_ERROR) { + mOnMalformedPdfFileListener.onMalformedPdfFile(); + mPageCount = PrintDocumentInfo.PAGE_COUNT_UNKNOWN; + } else { + mPageCount = pageCount; + } if (callback != null) { callback.run(); } diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java index 30808baaab872..e97693641c2cb 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java +++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java @@ -32,7 +32,6 @@ import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; -import android.widget.CheckBox; import android.widget.TextView; import com.android.printspooler.R; import com.android.printspooler.model.PageContentRepository; @@ -48,7 +47,8 @@ import java.util.List; /** * This class represents the adapter for the pages in the print preview list. */ -public final class PageAdapter extends Adapter { +public final class PageAdapter extends Adapter implements + PageContentRepository.OnMalformedPdfFileListener{ private static final String LOG_TAG = "PageAdapter"; private static final int MAX_PREVIEW_PAGES_BATCH = 50; @@ -75,7 +75,7 @@ public final class PageAdapter extends Adapter { private final Context mContext; private final LayoutInflater mLayoutInflater; - private final ContentUpdateRequestCallback mContentUpdateRequestCallback; + private final ContentCallbacks mCallbacks; private final PageContentRepository mPageContentRepository; private final PreviewArea mPreviewArea; @@ -109,8 +109,9 @@ public final class PageAdapter extends Adapter { private int mPageContentWidth; private int mPageContentHeight; - public interface ContentUpdateRequestCallback { - public void requestContentUpdate(); + public interface ContentCallbacks { + public void onRequestContentUpdate(); + public void onMalformedPdfFile(); } public interface PreviewArea { @@ -120,13 +121,12 @@ public final class PageAdapter extends Adapter { public void setPadding(int left, int top, int right, int bottom); } - public PageAdapter(Context context, ContentUpdateRequestCallback updateRequestCallback, - PreviewArea previewArea) { + public PageAdapter(Context context, ContentCallbacks callbacks, PreviewArea previewArea) { mContext = context; - mContentUpdateRequestCallback = updateRequestCallback; + mCallbacks = callbacks; mLayoutInflater = (LayoutInflater) context.getSystemService( Context.LAYOUT_INFLATER_SERVICE); - mPageContentRepository = new PageContentRepository(context); + mPageContentRepository = new PageContentRepository(context, this); mSelectedPageElevation = mContext.getResources().getDimension( R.dimen.selected_page_elevation); @@ -165,6 +165,11 @@ public final class PageAdapter extends Adapter { } } + @Override + public void onMalformedPdfFile() { + mCallbacks.onMalformedPdfFile(); + } + public void onOrientationChanged() { mColumnCount = mContext.getResources().getInteger( R.integer.preview_page_per_row_count); @@ -199,7 +204,7 @@ public final class PageAdapter extends Adapter { // If we already requested all pages, just wait. if (!Arrays.equals(ALL_PAGES_ARRAY, mRequestedPages)) { mRequestedPages = ALL_PAGES_ARRAY; - mContentUpdateRequestCallback.requestContentUpdate(); + mCallbacks.onRequestContentUpdate(); } return; } else { @@ -548,7 +553,7 @@ public final class PageAdapter extends Adapter { if (DEBUG) { Log.i(LOG_TAG, "Requesting pages: " + Arrays.toString(mRequestedPages)); } - mContentUpdateRequestCallback.requestContentUpdate(); + mCallbacks.onRequestContentUpdate(); } } diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java index 26dfb1a466dd1..86c3a9237cbe6 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java +++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java @@ -92,7 +92,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; public class PrintActivity extends Activity implements RemotePrintDocument.UpdateResultCallbacks, - PrintErrorFragment.OnActionListener, PageAdapter.ContentUpdateRequestCallback, + PrintErrorFragment.OnActionListener, PageAdapter.ContentCallbacks, OptionsStateChangeListener, OptionsStateController { private static final String LOG_TAG = "PrintActivity"; @@ -351,16 +351,26 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat } @Override - public void requestContentUpdate() { + public void onRequestContentUpdate() { if (canUpdateDocument()) { updateDocument(true, false); } } + @Override + public void onMalformedPdfFile() { + mProgressMessageController.cancel(); + ensureErrorUiShown(null, PrintErrorFragment.ACTION_RETRY); + + setState(STATE_UPDATE_FAILED); + + updateOptionsUi(); + } + @Override public void onActionPerformed() { - if (mState == STATE_UPDATE_FAILED && canUpdateDocument()) { - updateDocument(true, true); + if (mState == STATE_UPDATE_FAILED + && canUpdateDocument() && updateDocument(true, true)) { ensurePreviewUiShown(); setState(STATE_CONFIGURING); updateOptionsUi(); @@ -503,18 +513,15 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat switch (requestCode) { case ACTIVITY_REQUEST_CREATE_FILE: { onStartCreateDocumentActivityResult(resultCode, data); - } - break; + } break; case ACTIVITY_REQUEST_SELECT_PRINTER: { onSelectPrinterActivityResult(resultCode, data); - } - break; + } break; case ACTIVITY_REQUEST_POPULATE_ADVANCED_PRINT_OPTIONS: { onAdvancedPrintOptionsActivityResult(resultCode, data); - } - break; + } break; } }