am 3b42928c: Merge "Print spooler UI polish and bug fixes." into lmp-dev
* commit '3b42928c318d2732d75bb9c0ed7b864c47a265a2': Print spooler UI polish and bug fixes.
This commit is contained in:
@@ -535,7 +535,7 @@ public final class PrintManager {
|
||||
destroyed = isDestroyedLocked();
|
||||
}
|
||||
|
||||
if (destroyed) {
|
||||
if (destroyed && observer != null) {
|
||||
try {
|
||||
observer.onDestroy();
|
||||
} catch (RemoteException re) {
|
||||
|
||||
32
packages/PrintSpooler/res/layout/preview_page_loading.xml
Normal file
32
packages/PrintSpooler/res/layout/preview_page_loading.xml
Normal file
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -195,6 +195,7 @@ class PrintPreviewController implements MutexFileProvider.OnReleaseRequestCallba
|
||||
if (mPageAdapter.isOpened()) {
|
||||
mPageAdapter.close(null);
|
||||
}
|
||||
mRecyclerView.setAdapter(null);
|
||||
mPageAdapter.destroy();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user