diff options
9 files changed, 108 insertions, 49 deletions
diff --git a/core/java/android/print/PrintManager.java b/core/java/android/print/PrintManager.java index 9361286..bf8ac65 100644 --- a/core/java/android/print/PrintManager.java +++ b/core/java/android/print/PrintManager.java @@ -535,7 +535,7 @@ public final class PrintManager { destroyed = isDestroyedLocked(); } - if (destroyed) { + if (destroyed && observer != null) { try { observer.onDestroy(); } catch (RemoteException re) { diff --git a/packages/PrintSpooler/res/layout/preview_page_loading.xml b/packages/PrintSpooler/res/layout/preview_page_loading.xml new file mode 100644 index 0000000..1af3a17 --- /dev/null +++ b/packages/PrintSpooler/res/layout/preview_page_loading.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="fill_parent"> + + <ImageView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_margin="36dip" + android:layout_gravity="center" + android:src="@drawable/ic_grayedout_printer" + android:contentDescription="@null" + android:scaleType="centerInside" + android:adjustViewBounds="true"> + </ImageView> + +</FrameLayout> diff --git a/packages/PrintSpooler/res/values-land/constants.xml b/packages/PrintSpooler/res/values-land/constants.xml index 6cf9754..84fc050 100644 --- a/packages/PrintSpooler/res/values-land/constants.xml +++ b/packages/PrintSpooler/res/values-land/constants.xml @@ -16,7 +16,7 @@ <resources> - <integer name="preview_page_per_row_count">2</integer> + <integer name="preview_page_per_row_count">4</integer> <integer name="print_option_column_count">3</integer> diff --git a/packages/PrintSpooler/res/values/strings.xml b/packages/PrintSpooler/res/values/strings.xml index 5b7fda3..27e1d51 100644 --- a/packages/PrintSpooler/res/values/strings.xml +++ b/packages/PrintSpooler/res/values/strings.xml @@ -76,7 +76,6 @@ <!-- Title for the print dialog announced to the user for accessibility. Not shown in the UI. [CHAR LIMIT=none] --> <string name="print_dialog">Print dialog</string> - <!-- Template for the message that shows the current page out of the total number of pages --> <string name="current_page_template"><xliff:g id="current_page">%1$d</xliff:g> /<xliff:g id="page_count">%2$d</xliff:g></string> diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java index 09e8b39..1e7a011 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java +++ b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java @@ -317,6 +317,11 @@ public final class RemotePrintDocument { return mState == STATE_FAILED; } + public boolean hasLaidOutPages() { + return mDocumentInfo.info != null + && mDocumentInfo.info.getPageCount() > 0; + } + public void clearUpdateError() { if (!hasUpdateError()) { throw new IllegalStateException("No update error to clear"); diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java index d949673..ce0b9b6 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java +++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java @@ -17,6 +17,9 @@ package com.android.printspooler.ui; import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.drawable.BitmapDrawable; import android.os.ParcelFileDescriptor; import android.print.PageRange; import android.print.PrintAttributes.MediaSize; @@ -26,12 +29,12 @@ import android.support.v7.widget.RecyclerView.Adapter; import android.support.v7.widget.RecyclerView.ViewHolder; import android.util.Log; import android.util.SparseArray; -import android.util.TypedValue; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; +import android.view.View.MeasureSpec; import android.widget.TextView; import com.android.printspooler.R; import com.android.printspooler.model.PageContentRepository; @@ -48,7 +51,7 @@ import java.util.List; * This class represents the adapter for the pages in the print preview list. */ public final class PageAdapter extends Adapter implements - PageContentRepository.OnMalformedPdfFileListener{ + PageContentRepository.OnMalformedPdfFileListener { private static final String LOG_TAG = "PageAdapter"; private static final int MAX_PREVIEW_PAGES_BATCH = 50; @@ -86,6 +89,8 @@ public final class PageAdapter extends Adapter implements // Pages the user selected in the UI. private PageRange[] mSelectedPages; + private BitmapDrawable mEmptyState; + private int mDocumentPageCount = PrintDocumentInfo.PAGE_COUNT_UNKNOWN; private int mSelectedPageCount; @@ -257,7 +262,7 @@ public final class PageAdapter extends Adapter implements } if (updatePreviewAreaAndPageSize) { - updatePreviewAreaAndPageSize(); + updatePreviewAreaPageSizeAndEmptyState(); } if (documentChanged) { @@ -318,12 +323,12 @@ public final class PageAdapter extends Adapter implements } // OK, there are bugs in recycler view which tries to bind views - // without recycling them which would give us a chane to clean up. + // without recycling them which would give us a chance to clean up. PageContentProvider boundProvider = mPageContentRepository - .peekPageContentProvider(pageIndexInFile); + .peekPageContentProvider(pageIndexInFile); if (boundProvider != null) { PageContentView owner = (PageContentView) boundProvider.getOwner(); - owner.init(null, mMediaSize, mMinMargins); + owner.init(null, mEmptyState, mMediaSize, mMinMargins); mPageContentRepository.releasePageContentProvider(boundProvider); } @@ -333,7 +338,7 @@ public final class PageAdapter extends Adapter implements } else { onSelectedPageNotInFile(pageInDocument); } - content.init(provider, mMediaSize, mMinMargins); + content.init(provider, mEmptyState, mMediaSize, mMinMargins); View pageSelector = page.findViewById(R.id.page_selector); pageSelector.setTag(myHolder); @@ -384,7 +389,7 @@ public final class PageAdapter extends Adapter implements mSelectedPages = selectedPages; mSelectedPageCount = PageRangeUtils.getNormalizedPageCount( mSelectedPages, mDocumentPageCount); - updatePreviewAreaAndPageSize(); + updatePreviewAreaPageSizeAndEmptyState(); notifyDataSetChanged(); } return mSelectedPages; @@ -392,12 +397,12 @@ public final class PageAdapter extends Adapter implements public void onPreviewAreaSizeChanged() { if (mMediaSize != null) { - updatePreviewAreaAndPageSize(); + updatePreviewAreaPageSizeAndEmptyState(); notifyDataSetChanged(); } } - private void updatePreviewAreaAndPageSize() { + private void updatePreviewAreaPageSizeAndEmptyState() { final int availableWidth = mPreviewArea.getWidth(); final int availableHeight = mPreviewArea.getHeight(); @@ -419,7 +424,7 @@ public final class PageAdapter extends Adapter implements final int pageContentDesiredHeight = (int) (((float) pageContentDesiredWidth / pageAspectRatio) + 0.5f); - // If the page does not fit entirely in a vertial direction, + // If the page does not fit entirely in a vertical direction, // we shirk it but not less than the minimal page width. final int pageContentMinHeight = (int) (mPreviewPageMinWidth / pageAspectRatio + 0.5f); final int pageContentMaxHeight = Math.max(pageContentMinHeight, @@ -448,6 +453,23 @@ public final class PageAdapter extends Adapter implements mPreviewArea.setPadding(horizontalPadding, verticalPadding, horizontalPadding, verticalPadding); + + // Now update the empty state drawable, as it depends on the page + // size and is reused for all views for better performance. + LayoutInflater inflater = LayoutInflater.from(mContext); + View content = inflater.inflate(R.layout.preview_page_loading, null, false); + content.measure(MeasureSpec.makeMeasureSpec(mPageContentWidth, MeasureSpec.EXACTLY), + MeasureSpec.makeMeasureSpec(mPageContentHeight, MeasureSpec.EXACTLY)); + content.layout(0, 0, content.getMeasuredWidth(), content.getMeasuredHeight()); + + Bitmap bitmap = Bitmap.createBitmap(mPageContentWidth, mPageContentHeight, + Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(bitmap); + content.draw(canvas); + + // Do not recycle the old bitmap if such as it may be set as an empty + // state to any of the page views. Just let the GC take care of it. + mEmptyState = new BitmapDrawable(mContext.getResources(), bitmap); } private PageRange[] computeSelectedPages() { @@ -718,7 +740,7 @@ public final class PageAdapter extends Adapter implements private void recyclePageView(PageContentView page, int pageIndexInAdapter) { PageContentProvider provider = page.getPageContentProvider(); if (provider != null) { - page.init(null, null, null); + page.init(null, null, null, null); mPageContentRepository.releasePageContentProvider(provider); mBoundPagesInAdapter.remove(pageIndexInAdapter); } diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java index 022e0d0..535081f 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java +++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java @@ -114,14 +114,15 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat private static final int DEST_ADAPTER_ITEM_ID_SAVE_AS_PDF = Integer.MAX_VALUE; private static final int DEST_ADAPTER_ITEM_ID_ALL_PRINTERS = Integer.MAX_VALUE - 1; - private static final int STATE_CONFIGURING = 0; - private static final int STATE_PRINT_CONFIRMED = 1; - private static final int STATE_PRINT_CANCELED = 2; - private static final int STATE_UPDATE_FAILED = 3; - private static final int STATE_CREATE_FILE_FAILED = 4; - private static final int STATE_PRINTER_UNAVAILABLE = 5; - private static final int STATE_UPDATE_SLOW = 6; - private static final int STATE_PRINT_COMPLETED = 7; + private static final int STATE_INITIALIZING = 0; + private static final int STATE_CONFIGURING = 1; + private static final int STATE_PRINT_CONFIRMED = 2; + private static final int STATE_PRINT_CANCELED = 3; + private static final int STATE_UPDATE_FAILED = 4; + private static final int STATE_CREATE_FILE_FAILED = 5; + private static final int STATE_PRINTER_UNAVAILABLE = 6; + private static final int STATE_UPDATE_SLOW = 7; + private static final int STATE_PRINT_COMPLETED = 8; private static final int UI_STATE_PREVIEW = 0; private static final int UI_STATE_ERROR = 1; @@ -196,7 +197,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat private int mCurrentPageCount; - private int mState; + private int mState = STATE_INITIALIZING; private int mUiState = UI_STATE_PREVIEW; @@ -290,10 +291,17 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat mPrintedDocument.start(); ensurePreviewUiShown(); + + setState(STATE_CONFIGURING); } @Override public void onPause() { + if (mState == STATE_INITIALIZING) { + super.onPause(); + return; + } + if (isFinishing()) { PrintSpoolerService spooler = mSpoolerProvider.getSpooler(); spooler.updatePrintJobUserConfigurableOptionsNoPersistence(mPrintJob); @@ -341,9 +349,13 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat @Override public boolean onKeyUp(int keyCode, KeyEvent event) { + if (mState == STATE_INITIALIZING) { + return super.onKeyUp(keyCode, event); + } + if (keyCode == KeyEvent.KEYCODE_BACK && event.isTracking() && !event.isCanceled()) { - if (mPrintPreviewController != null&&mPrintPreviewController.isOptionsOpened() + if (mPrintPreviewController != null && mPrintPreviewController.isOptionsOpened() && !hasErrors()) { mPrintPreviewController.closeOptions(); } else { @@ -900,7 +912,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat final boolean willUpdate = mPrintedDocument.update(mPrintJob.getAttributes(), pages, preview); - if (willUpdate) { + if (willUpdate && !mPrintedDocument.hasLaidOutPages()) { // When the update is done we update the print preview. mProgressMessageController.post(); return true; diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewController.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewController.java index 2b5b41b..a25e05e 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewController.java +++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewController.java @@ -195,6 +195,7 @@ class PrintPreviewController implements MutexFileProvider.OnReleaseRequestCallba if (mPageAdapter.isOpened()) { mPageAdapter.close(null); } + mRecyclerView.setAdapter(null); mPageAdapter.destroy(); } diff --git a/packages/PrintSpooler/src/com/android/printspooler/widget/PageContentView.java b/packages/PrintSpooler/src/com/android/printspooler/widget/PageContentView.java index 23a01bd..e2ae758 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/widget/PageContentView.java +++ b/packages/PrintSpooler/src/com/android/printspooler/widget/PageContentView.java @@ -17,17 +17,15 @@ package com.android.printspooler.widget; import android.content.Context; -import android.graphics.Canvas; import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; import android.print.PrintAttributes.MediaSize; import android.print.PrintAttributes.Margins; import android.util.AttributeSet; -import android.util.TypedValue; import android.view.View; import com.android.printspooler.model.PageContentRepository; -import com.android.printspooler.model.PageContentRepository.PageContentProvider; import com.android.printspooler.model.PageContentRepository.RenderSpec; +import com.android.printspooler.model.PageContentRepository.PageContentProvider; /** * This class represents a page in the print preview list. The width of the page @@ -37,35 +35,20 @@ import com.android.printspooler.model.PageContentRepository.RenderSpec; */ public class PageContentView extends View implements PageContentRepository.OnPageContentAvailableCallback { - - private final ColorDrawable mEmptyState; - private PageContentProvider mProvider; private MediaSize mMediaSize; private Margins mMinMargins; + private Drawable mEmptyState; + private boolean mContentRequested; private boolean mNeedsLayout; public PageContentView(Context context, AttributeSet attrs) { super(context, attrs); - - TypedValue typedValue = new TypedValue(); - context.getTheme().resolveAttribute(com.android.internal.R.attr.textColorPrimary, - typedValue, true); - - mEmptyState = new ColorDrawable(typedValue.data); - - setBackground(mEmptyState); - } - - @Override - protected void onDraw(Canvas canvas) { - super.onDraw(canvas); - requestPageContentIfNeeded(); } @Override @@ -85,15 +68,19 @@ public class PageContentView extends View return mProvider; } - public void init(PageContentProvider provider, MediaSize mediaSize, Margins minMargins) { + public void init(PageContentProvider provider, Drawable emptyState, + MediaSize mediaSize, Margins minMargins) { final boolean providerChanged = (mProvider == null) ? provider != null : !mProvider.equals(provider); + final boolean loadingDrawableChanged = (mEmptyState == null) + ? mEmptyState != null : !mEmptyState.equals(emptyState); final boolean mediaSizeChanged = (mMediaSize == null) ? mediaSize != null : !mMediaSize.equals(mediaSize); final boolean marginsChanged = (mMinMargins == null) ? minMargins != null : !mMinMargins.equals(minMargins); - if (!providerChanged && !mediaSizeChanged && !marginsChanged) { + if (!providerChanged && !mediaSizeChanged + && !marginsChanged && !loadingDrawableChanged) { return; } @@ -101,6 +88,7 @@ public class PageContentView extends View mMediaSize = mediaSize; mMinMargins = minMargins; + mEmptyState = emptyState; mContentRequested = false; mNeedsLayout = mNeedsLayout || mediaSizeChanged || marginsChanged; |