FileDocCategorySizeDatePackage
PageAdapter.javaAPI DocAndroid 5.1 API30220Thu Mar 12 22:22:42 GMT 2015com.android.printspooler.ui

PageAdapter

public final class PageAdapter extends android.support.v7.widget.RecyclerView.Adapter
This class represents the adapter for the pages in the print preview list.

Fields Summary
private static final String
LOG_TAG
private static final int
MAX_PREVIEW_PAGES_BATCH
private static final boolean
DEBUG
private static final android.print.PageRange[]
ALL_PAGES_ARRAY
private static final int
INVALID_PAGE_INDEX
private static final int
STATE_CLOSED
private static final int
STATE_OPENED
private static final int
STATE_DESTROYED
private final dalvik.system.CloseGuard
mCloseGuard
private final android.util.SparseArray
mBoundPagesInAdapter
private final android.util.SparseArray
mConfirmedPagesInDocument
private final PageClickListener
mPageClickListener
private final android.content.Context
mContext
private final android.view.LayoutInflater
mLayoutInflater
private final ContentCallbacks
mCallbacks
private final com.android.printspooler.model.PageContentRepository
mPageContentRepository
private final PreviewArea
mPreviewArea
private android.print.PageRange[]
mRequestedPages
private android.print.PageRange[]
mWrittenPages
private android.print.PageRange[]
mSelectedPages
private android.graphics.drawable.BitmapDrawable
mEmptyState
private int
mDocumentPageCount
private int
mSelectedPageCount
private int
mPreviewPageMargin
private int
mPreviewPageMinWidth
private int
mPreviewListPadding
private int
mFooterHeight
private int
mColumnCount
private android.print.PrintAttributes.MediaSize
mMediaSize
private android.print.PrintAttributes.Margins
mMinMargins
private int
mState
private int
mPageContentWidth
private int
mPageContentHeight
Constructors Summary
public PageAdapter(android.content.Context context, ContentCallbacks callbacks, PreviewArea previewArea)


       
          
          
          
    

       
          
          
           
                 
    

           
        mContext = context;
        mCallbacks = callbacks;
        mLayoutInflater = (LayoutInflater) context.getSystemService(
                Context.LAYOUT_INFLATER_SERVICE);
        mPageContentRepository = new PageContentRepository(context);

        mPreviewPageMargin = mContext.getResources().getDimensionPixelSize(
                R.dimen.preview_page_margin);

        mPreviewPageMinWidth = mContext.getResources().getDimensionPixelSize(
                R.dimen.preview_page_min_width);

        mPreviewListPadding = mContext.getResources().getDimensionPixelSize(
                R.dimen.preview_list_padding);

        mColumnCount = mContext.getResources().getInteger(
                R.integer.preview_page_per_row_count);

        mFooterHeight = mContext.getResources().getDimensionPixelSize(
                R.dimen.preview_page_footer_height);

        mPreviewArea = previewArea;

        mCloseGuard.open("destroy");

        setHasStableIds(true);

        mState = STATE_CLOSED;
        if (DEBUG) {
            Log.i(LOG_TAG, "STATE_CLOSED");
        }
    
Methods Summary
public voidclose(java.lang.Runnable callback)

        throwIfNotOpened();
        mState = STATE_CLOSED;
        if (DEBUG) {
            Log.i(LOG_TAG, "STATE_CLOSED");
        }
        mPageContentRepository.close(callback);
    
private android.print.PageRange[]computeBoundPagesInDocument()

        List<PageRange> pagesInDocumentList = new ArrayList<>();

        int fromPage = INVALID_PAGE_INDEX;
        int toPage = INVALID_PAGE_INDEX;

        final int boundPageCount = mBoundPagesInAdapter.size();
        for (int i = 0; i < boundPageCount; i++) {
            // The container is a sparse array, so keys are sorted in ascending order.
            final int boundPageInAdapter = mBoundPagesInAdapter.keyAt(i);
            final int boundPageInDocument = computePageIndexInDocument(boundPageInAdapter);

            if (fromPage == INVALID_PAGE_INDEX) {
                fromPage = boundPageInDocument;
            }

            if (toPage == INVALID_PAGE_INDEX) {
                toPage = boundPageInDocument;
            }

            if (boundPageInDocument > toPage + 1) {
                PageRange pageRange = new PageRange(fromPage, toPage);
                pagesInDocumentList.add(pageRange);
                fromPage = toPage = boundPageInDocument;
            } else {
                toPage = boundPageInDocument;
            }
        }

        if (fromPage != INVALID_PAGE_INDEX && toPage != INVALID_PAGE_INDEX) {
            PageRange pageRange = new PageRange(fromPage, toPage);
            pagesInDocumentList.add(pageRange);
        }

        PageRange[] pageInDocument = new PageRange[pagesInDocumentList.size()];
        pagesInDocumentList.toArray(pageInDocument);

        if (DEBUG) {
            Log.i(LOG_TAG, "Bound pages: " + Arrays.toString(pageInDocument));
        }

        return pageInDocument;
    
private intcomputePageIndexInDocument(int indexInAdapter)

        int skippedAdapterPages = 0;
        final int selectedPagesCount = mSelectedPages.length;
        for (int i = 0; i < selectedPagesCount; i++) {
            PageRange pageRange = PageRangeUtils.asAbsoluteRange(
                    mSelectedPages[i], mDocumentPageCount);
            skippedAdapterPages += pageRange.getSize();
            if (skippedAdapterPages > indexInAdapter) {
                final int overshoot = skippedAdapterPages - indexInAdapter - 1;
                return pageRange.getEnd() - overshoot;
            }
        }
        return INVALID_PAGE_INDEX;
    
private intcomputePageIndexInFile(int pageIndexInDocument)

        if (!PageRangeUtils.contains(mSelectedPages, pageIndexInDocument)) {
            return INVALID_PAGE_INDEX;
        }
        if (mWrittenPages == null) {
            return INVALID_PAGE_INDEX;
        }

        int indexInFile = INVALID_PAGE_INDEX;
        final int rangeCount = mWrittenPages.length;
        for (int i = 0; i < rangeCount; i++) {
            PageRange pageRange = mWrittenPages[i];
            if (!pageRange.contains(pageIndexInDocument)) {
                indexInFile += pageRange.getSize();
            } else {
                indexInFile += pageIndexInDocument - pageRange.getStart() + 1;
                return indexInFile;
            }
        }
        return INVALID_PAGE_INDEX;
    
private android.print.PageRange[]computeRequestedPages(int pageInDocument)

        if (mRequestedPages != null &&
                PageRangeUtils.contains(mRequestedPages, pageInDocument)) {
            return mRequestedPages;
        }

        List<PageRange> pageRangesList = new ArrayList<>();

        int remainingPagesToRequest = MAX_PREVIEW_PAGES_BATCH;
        final int selectedPagesCount = mSelectedPages.length;

        // We always request the pages that are bound, i.e. shown on screen.
        PageRange[] boundPagesInDocument = computeBoundPagesInDocument();

        final int boundRangeCount = boundPagesInDocument.length;
        for (int i = 0; i < boundRangeCount; i++) {
            PageRange boundRange = boundPagesInDocument[i];
            pageRangesList.add(boundRange);
        }
        remainingPagesToRequest -= PageRangeUtils.getNormalizedPageCount(
                boundPagesInDocument, mDocumentPageCount);

        final boolean requestFromStart = mRequestedPages == null
                || pageInDocument > mRequestedPages[mRequestedPages.length - 1].getEnd();

        if (!requestFromStart) {
            if (DEBUG) {
                Log.i(LOG_TAG, "Requesting from end");
            }

            // Reminder that ranges are always normalized.
            for (int i = selectedPagesCount - 1; i >= 0; i--) {
                if (remainingPagesToRequest <= 0) {
                    break;
                }

                PageRange selectedRange = PageRangeUtils.asAbsoluteRange(mSelectedPages[i],
                        mDocumentPageCount);
                if (pageInDocument < selectedRange.getStart()) {
                    continue;
                }

                PageRange pagesInRange;
                int rangeSpan;

                if (selectedRange.contains(pageInDocument)) {
                    rangeSpan = pageInDocument - selectedRange.getStart() + 1;
                    rangeSpan = Math.min(rangeSpan, remainingPagesToRequest);
                    final int fromPage = Math.max(pageInDocument - rangeSpan - 1, 0);
                    rangeSpan = Math.max(rangeSpan, 0);
                    pagesInRange = new PageRange(fromPage, pageInDocument);
                } else {
                    rangeSpan = selectedRange.getSize();
                    rangeSpan = Math.min(rangeSpan, remainingPagesToRequest);
                    rangeSpan = Math.max(rangeSpan, 0);
                    final int fromPage = Math.max(selectedRange.getEnd() - rangeSpan - 1, 0);
                    final int toPage = selectedRange.getEnd();
                    pagesInRange = new PageRange(fromPage, toPage);
                }

                pageRangesList.add(pagesInRange);
                remainingPagesToRequest -= rangeSpan;
            }
        } else {
            if (DEBUG) {
                Log.i(LOG_TAG, "Requesting from start");
            }

            // Reminder that ranges are always normalized.
            for (int i = 0; i < selectedPagesCount; i++) {
                if (remainingPagesToRequest <= 0) {
                    break;
                }

                PageRange selectedRange = PageRangeUtils.asAbsoluteRange(mSelectedPages[i],
                        mDocumentPageCount);
                if (pageInDocument > selectedRange.getEnd()) {
                    continue;
                }

                PageRange pagesInRange;
                int rangeSpan;

                if (selectedRange.contains(pageInDocument)) {
                    rangeSpan = selectedRange.getEnd() - pageInDocument + 1;
                    rangeSpan = Math.min(rangeSpan, remainingPagesToRequest);
                    final int toPage = Math.min(pageInDocument + rangeSpan - 1,
                            mDocumentPageCount - 1);
                    pagesInRange = new PageRange(pageInDocument, toPage);
                } else {
                    rangeSpan = selectedRange.getSize();
                    rangeSpan = Math.min(rangeSpan, remainingPagesToRequest);
                    final int fromPage = selectedRange.getStart();
                    final int toPage = Math.min(selectedRange.getStart() + rangeSpan - 1,
                            mDocumentPageCount - 1);
                    pagesInRange = new PageRange(fromPage, toPage);
                }

                if (DEBUG) {
                    Log.i(LOG_TAG, "computeRequestedPages() Adding range:" + pagesInRange);
                }
                pageRangesList.add(pagesInRange);
                remainingPagesToRequest -= rangeSpan;
            }
        }

        PageRange[] pageRanges = new PageRange[pageRangesList.size()];
        pageRangesList.toArray(pageRanges);

        return PageRangeUtils.normalize(pageRanges);
    
private android.print.PageRange[]computeSelectedPages()

        ArrayList<PageRange> selectedPagesList = new ArrayList<>();

        int startPageIndex = INVALID_PAGE_INDEX;
        int endPageIndex = INVALID_PAGE_INDEX;

        final int pageCount = mConfirmedPagesInDocument.size();
        for (int i = 0; i < pageCount; i++) {
            final int pageIndex = mConfirmedPagesInDocument.keyAt(i);
            if (startPageIndex == INVALID_PAGE_INDEX) {
                startPageIndex = endPageIndex = pageIndex;
            }
            if (endPageIndex + 1 < pageIndex) {
                PageRange pageRange = new PageRange(startPageIndex, endPageIndex);
                selectedPagesList.add(pageRange);
                startPageIndex = pageIndex;
            }
            endPageIndex = pageIndex;
        }

        if (startPageIndex != INVALID_PAGE_INDEX
                && endPageIndex != INVALID_PAGE_INDEX) {
            PageRange pageRange = new PageRange(startPageIndex, endPageIndex);
            selectedPagesList.add(pageRange);
        }

        PageRange[] selectedPages = new PageRange[selectedPagesList.size()];
        selectedPagesList.toArray(selectedPages);

        return selectedPages;
    
public voiddestroy(java.lang.Runnable callback)

        mCloseGuard.close();
        mState = STATE_DESTROYED;
        if (DEBUG) {
            Log.i(LOG_TAG, "STATE_DESTROYED");
        }
        mPageContentRepository.destroy(callback);
    
protected voidfinalize()

        try {
            if (mState != STATE_DESTROYED) {
                mCloseGuard.warnIfOpen();
                destroy(null);
            }
        } finally {
            super.finalize();
        }
    
public intgetFilePageCount()

        return mPageContentRepository.getFilePageCount();
    
public intgetItemCount()

        return mSelectedPageCount;
    
public longgetItemId(int position)

        return computePageIndexInDocument(position);
    
public android.print.PageRange[]getRequestedPages()

        return mRequestedPages;
    
public android.print.PageRange[]getSelectedPages()

        PageRange[] selectedPages = computeSelectedPages();
        if (!Arrays.equals(mSelectedPages, selectedPages)) {
            mSelectedPages = selectedPages;
            mSelectedPageCount = PageRangeUtils.getNormalizedPageCount(
                    mSelectedPages, mDocumentPageCount);
            updatePreviewAreaPageSizeAndEmptyState();
            notifyDataSetChanged();
        }
        return mSelectedPages;
    
public booleanisOpened()

        return mState == STATE_OPENED;
    
public voidonBindViewHolder(android.support.v7.widget.RecyclerView.ViewHolder holder, int position)

        if (DEBUG) {
            Log.i(LOG_TAG, "Binding holder: " + holder + " with id: " + getItemId(position)
                    + " for position: " + position);
        }

        MyViewHolder myHolder = (MyViewHolder) holder;

        PreviewPageFrame page = (PreviewPageFrame) holder.itemView;
        page.setOnClickListener(mPageClickListener);

        page.setTag(holder);

        myHolder.mPageInAdapter = position;

        final int pageInDocument = computePageIndexInDocument(position);
        final int pageIndexInFile = computePageIndexInFile(pageInDocument);

        PageContentView content = (PageContentView) page.findViewById(R.id.page_content);

        LayoutParams params = content.getLayoutParams();
        params.width = mPageContentWidth;
        params.height = mPageContentHeight;

        PageContentProvider provider = content.getPageContentProvider();

        if (pageIndexInFile != INVALID_PAGE_INDEX) {
            if (DEBUG) {
                Log.i(LOG_TAG, "Binding provider:"
                        + " pageIndexInAdapter: " + position
                        + ", pageInDocument: " + pageInDocument
                        + ", pageIndexInFile: " + pageIndexInFile);
            }

            provider = mPageContentRepository.acquirePageContentProvider(
                    pageIndexInFile, content);
            mBoundPagesInAdapter.put(position, null);
        } else {
            onSelectedPageNotInFile(pageInDocument);
        }
        content.init(provider, mEmptyState, mMediaSize, mMinMargins);

        if (mConfirmedPagesInDocument.indexOfKey(pageInDocument) >= 0) {
            page.setSelected(true, false);
        } else {
            page.setSelected(false, false);
        }

        page.setContentDescription(mContext.getString(R.string.page_description_template,
                pageInDocument + 1, mDocumentPageCount));

        TextView pageNumberView = (TextView) page.findViewById(R.id.page_number);
        String text = mContext.getString(R.string.current_page_template,
                pageInDocument + 1, mDocumentPageCount);
        pageNumberView.setText(text);
    
public android.support.v7.widget.RecyclerView.ViewHolderonCreateViewHolder(android.view.ViewGroup parent, int viewType)

        View page = mLayoutInflater.inflate(R.layout.preview_page, parent, false);
        return new MyViewHolder(page);
    
public voidonOrientationChanged()

        mColumnCount = mContext.getResources().getInteger(
                R.integer.preview_page_per_row_count);
        notifyDataSetChanged();
    
public voidonPreviewAreaSizeChanged()

        if (mMediaSize != null) {
            updatePreviewAreaPageSizeAndEmptyState();
            notifyDataSetChanged();
        }
    
private voidonSelectedPageNotInFile(int pageInDocument)

        PageRange[] requestedPages = computeRequestedPages(pageInDocument);
        if (!Arrays.equals(mRequestedPages, requestedPages)) {
            mRequestedPages = requestedPages;
            if (DEBUG) {
                Log.i(LOG_TAG, "Requesting pages: " + Arrays.toString(mRequestedPages));
            }
            mCallbacks.onRequestContentUpdate();
        }
    
public voidonViewRecycled(android.support.v7.widget.RecyclerView.ViewHolder holder)

        MyViewHolder myHolder = (MyViewHolder) holder;
        PageContentView content = (PageContentView) holder.itemView
                .findViewById(R.id.page_content);
        recyclePageView(content, myHolder.mPageInAdapter);
        myHolder.mPageInAdapter = INVALID_PAGE_INDEX;
    
public voidopen(android.os.ParcelFileDescriptor source, java.lang.Runnable callback)

        throwIfNotClosed();
        mState = STATE_OPENED;
        if (DEBUG) {
            Log.i(LOG_TAG, "STATE_OPENED");
        }
        mPageContentRepository.open(source, new OpenDocumentCallback() {
            @Override
            public void onSuccess() {
                notifyDataSetChanged();
                callback.run();
            }

            @Override
            public void onFailure(int error) {
                switch (error) {
                    case OpenDocumentCallback.ERROR_MALFORMED_PDF_FILE: {
                        mCallbacks.onMalformedPdfFile();
                    } break;

                    case OpenDocumentCallback.ERROR_SECURE_PDF_FILE: {
                        mCallbacks.onSecurePdfFile();
                    } break;
                }
            }
        });
    
private voidrecyclePageView(com.android.printspooler.widget.PageContentView page, int pageIndexInAdapter)

        PageContentProvider provider = page.getPageContentProvider();
        if (provider != null) {
            page.init(null, mEmptyState, mMediaSize, mMinMargins);
            mPageContentRepository.releasePageContentProvider(provider);
        }
        mBoundPagesInAdapter.remove(pageIndexInAdapter);
        page.setTag(null);
    
private voidsetConfirmedPages(android.print.PageRange[] pagesInDocument, int documentPageCount)

        mConfirmedPagesInDocument.clear();
        final int rangeCount = pagesInDocument.length;
        for (int i = 0; i < rangeCount; i++) {
            PageRange pageRange = PageRangeUtils.asAbsoluteRange(pagesInDocument[i],
                    documentPageCount);
            for (int j = pageRange.getStart(); j <= pageRange.getEnd(); j++) {
                mConfirmedPagesInDocument.put(j, null);
            }
        }
    
public voidstartPreloadContent(android.print.PageRange pageRangeInAdapter)

        final int startPageInDocument = computePageIndexInDocument(pageRangeInAdapter.getStart());
        final int startPageInFile = computePageIndexInFile(startPageInDocument);
        final int endPageInDocument = computePageIndexInDocument(pageRangeInAdapter.getEnd());
        final int endPageInFile = computePageIndexInFile(endPageInDocument);
        if (startPageInDocument != INVALID_PAGE_INDEX && endPageInDocument != INVALID_PAGE_INDEX) {
            mPageContentRepository.startPreload(startPageInFile, endPageInFile);
        }
    
public voidstopPreloadContent()

        mPageContentRepository.stopPreload();
    
private voidthrowIfNotClosed()

        if (mState != STATE_CLOSED) {
            throw new IllegalStateException("Not closed");
        }
    
private voidthrowIfNotOpened()

        if (mState != STATE_OPENED) {
            throw new IllegalStateException("Not opened");
        }
    
public voidupdate(android.print.PageRange[] writtenPages, android.print.PageRange[] selectedPages, int documentPageCount, android.print.PrintAttributes.MediaSize mediaSize, android.print.PrintAttributes.Margins minMargins)

        boolean documentChanged = false;
        boolean updatePreviewAreaAndPageSize = false;

        // If the app does not tell how many pages are in the document we cannot
        // optimize and ask for all pages whose count we get from the renderer.
        if (documentPageCount == PrintDocumentInfo.PAGE_COUNT_UNKNOWN) {
            if (writtenPages == null) {
                // If we already requested all pages, just wait.
                if (!Arrays.equals(ALL_PAGES_ARRAY, mRequestedPages)) {
                    mRequestedPages = ALL_PAGES_ARRAY;
                    mCallbacks.onRequestContentUpdate();
                }
                return;
            } else {
                documentPageCount = mPageContentRepository.getFilePageCount();
                if (documentPageCount <= 0) {
                    return;
                }
            }
        }

        if (!Arrays.equals(mSelectedPages, selectedPages)) {
            mSelectedPages = selectedPages;
            mSelectedPageCount = PageRangeUtils.getNormalizedPageCount(
                    mSelectedPages, documentPageCount);
            setConfirmedPages(mSelectedPages, documentPageCount);
            updatePreviewAreaAndPageSize = true;
            documentChanged = true;
        }

        if (mDocumentPageCount != documentPageCount) {
            mDocumentPageCount = documentPageCount;
            documentChanged = true;
        }

        if (mMediaSize == null || !mMediaSize.equals(mediaSize)) {
            mMediaSize = mediaSize;
            updatePreviewAreaAndPageSize = true;
            documentChanged = true;
        }

        if (mMinMargins == null || !mMinMargins.equals(minMargins)) {
            mMinMargins = minMargins;
            updatePreviewAreaAndPageSize = true;
            documentChanged = true;
        }

        // If *all pages* is selected we need to convert that to absolute
        // range as we will be checking if some pages are written or not.
        if (writtenPages != null) {
            // If we get all pages, this means all pages that we requested.
            if (PageRangeUtils.isAllPages(writtenPages)) {
                writtenPages = mRequestedPages;
            }
            if (!Arrays.equals(mWrittenPages, writtenPages)) {
                // TODO: Do a surgical invalidation of only written pages changed.
                mWrittenPages = writtenPages;
                documentChanged = true;
            }
        }

        if (updatePreviewAreaAndPageSize) {
            updatePreviewAreaPageSizeAndEmptyState();
        }

        if (documentChanged) {
            notifyDataSetChanged();
        }
    
private voidupdatePreviewAreaPageSizeAndEmptyState()

        if (mMediaSize == null) {
            return;
        }

        final int availableWidth = mPreviewArea.getWidth();
        final int availableHeight = mPreviewArea.getHeight();

        // Page aspect ratio to keep.
        final float pageAspectRatio = (float) mMediaSize.getWidthMils()
                / mMediaSize.getHeightMils();

        // Make sure we have no empty columns.
        final int columnCount = Math.min(mSelectedPageCount, mColumnCount);
        mPreviewArea.setColumnCount(columnCount);

        // Compute max page width.
        final int horizontalMargins = 2 * columnCount * mPreviewPageMargin;
        final int horizontalPaddingAndMargins = horizontalMargins + 2 * mPreviewListPadding;
        final int pageContentDesiredWidth = (int) ((((float) availableWidth
                - horizontalPaddingAndMargins) / columnCount) + 0.5f);

        // Compute max page height.
        final int pageContentDesiredHeight = (int) (((float) pageContentDesiredWidth
                / pageAspectRatio) + 0.5f);

        // 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,
                availableHeight - 2 * (mPreviewListPadding + mPreviewPageMargin) - mFooterHeight);

        mPageContentHeight = Math.min(pageContentDesiredHeight, pageContentMaxHeight);
        mPageContentWidth = (int) ((mPageContentHeight * pageAspectRatio) + 0.5f);

        final int totalContentWidth = columnCount * mPageContentWidth + horizontalMargins;
        final int horizontalPadding = (availableWidth - totalContentWidth) / 2;

        final int rowCount = mSelectedPageCount / columnCount
                + ((mSelectedPageCount % columnCount) > 0 ? 1 : 0);
        final int totalContentHeight = rowCount * (mPageContentHeight + mFooterHeight + 2
                * mPreviewPageMargin);

        final int verticalPadding;
        if (mPageContentHeight + mFooterHeight + mPreviewListPadding
                + 2 * mPreviewPageMargin > availableHeight) {
            verticalPadding = Math.max(0,
                    (availableHeight - mPageContentHeight - mFooterHeight) / 2
                            - mPreviewPageMargin);
        } else {
            verticalPadding = Math.max(mPreviewListPadding,
                    (availableHeight - totalContentHeight) / 2);
        }

        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);