Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9bab45a2 authored by Philip P. Moltmann's avatar Philip P. Moltmann
Browse files

Only preload selected pages

Otherwise if only some pages are selected all (non-selected) pages in
between are preloaded.

Test: Selected only some pages of a large document and observed which
      pages got preloaded
      cts-tradefed run cts-dev -m Print
Fixes: 62296301
Change-Id: I3a97cfa6991e5a95ff73628c4bb540c629160c0c
parent ef055443
Loading
Loading
Loading
Loading
+92 −32
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.printspooler.model;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
@@ -29,21 +31,27 @@ import android.os.AsyncTask;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.print.PageRange;
import android.print.PrintAttributes;
import android.print.PrintAttributes.MediaSize;
import android.print.PrintAttributes.Margins;
import android.print.PrintAttributes.MediaSize;
import android.print.PrintDocumentInfo;
import android.util.ArrayMap;
import android.util.Log;
import android.view.View;

import com.android.internal.annotations.GuardedBy;
import com.android.printspooler.renderer.IPdfRenderer;
import com.android.printspooler.renderer.PdfManipulationService;
import com.android.printspooler.util.BitmapSerializeUtils;
import com.android.printspooler.util.PageRangeUtils;

import dalvik.system.CloseGuard;

import libcore.io.IoUtils;

import java.io.IOException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
@@ -69,8 +77,9 @@ public final class PageContentRepository {

    private RenderSpec mLastRenderSpec;

    private int mScheduledPreloadFirstShownPage = INVALID_PAGE_INDEX;
    private int mScheduledPreloadLastShownPage = INVALID_PAGE_INDEX;
    @Nullable private PageRange mScheduledPreloadVisiblePages;
    @Nullable private PageRange[] mScheduledPreloadSelectedPages;
    @Nullable private PageRange[] mScheduledPreloadWrittenPages;

    private int mState;

@@ -129,14 +138,24 @@ public final class PageContentRepository {
        }
    }

    public void startPreload(int firstShownPage, int lastShownPage) {
    /**
     * Preload selected, written pages around visiblePages.
     *
     * @param visiblePages The pages currently visible
     * @param selectedPages The pages currently selected (e.g. they might become visible by
     *                      scrolling)
     * @param writtenPages The pages currently in the document
     */
    public void startPreload(@NonNull PageRange visiblePages, @NonNull PageRange[] selectedPages,
            @NonNull PageRange[] writtenPages) {
        // If we do not have a render spec we have no clue what size the
        // preloaded bitmaps should be, so just take a note for what to do.
        if (mLastRenderSpec == null) {
            mScheduledPreloadFirstShownPage = firstShownPage;
            mScheduledPreloadLastShownPage = lastShownPage;
            mScheduledPreloadVisiblePages = visiblePages;
            mScheduledPreloadSelectedPages = selectedPages;
            mScheduledPreloadWrittenPages = writtenPages;
        } else if (mState == STATE_OPENED) {
            mRenderer.startPreload(firstShownPage, lastShownPage, mLastRenderSpec);
            mRenderer.startPreload(visiblePages, selectedPages, writtenPages, mLastRenderSpec);
        }
    }

@@ -222,11 +241,12 @@ public final class PageContentRepository {

            // We tired to preload but didn't know the bitmap size, now
            // that we know let us do the work.
            if (mScheduledPreloadFirstShownPage != INVALID_PAGE_INDEX
                    && mScheduledPreloadLastShownPage != INVALID_PAGE_INDEX) {
                startPreload(mScheduledPreloadFirstShownPage, mScheduledPreloadLastShownPage);
                mScheduledPreloadFirstShownPage = INVALID_PAGE_INDEX;
                mScheduledPreloadLastShownPage = INVALID_PAGE_INDEX;
            if (mScheduledPreloadVisiblePages != null) {
                startPreload(mScheduledPreloadVisiblePages, mScheduledPreloadSelectedPages,
                        mScheduledPreloadWrittenPages);
                mScheduledPreloadVisiblePages = null;
                mScheduledPreloadSelectedPages = null;
                mScheduledPreloadWrittenPages = null;
            }

            if (mState == STATE_OPENED) {
@@ -523,10 +543,45 @@ public final class PageContentRepository {
            mDestroyed = true;
        }

        public void startPreload(int firstShownPage, int lastShownPage, RenderSpec renderSpec) {
        /**
         * How many pages are {@code pages} before pageNum. E.g. page 5 in [0-1], [4-7] has the
         * index 4.
         *
         * @param pageNum The number of the page to find
         * @param pages A normalized array of page ranges
         *
         * @return The index or {@link #INVALID_PAGE_INDEX} if not found
         */
        private int findIndexOfPage(int pageNum, @NonNull PageRange[] pages) {
            int pagesBefore = 0;
            for (int i = 0; i < pages.length; i++) {
                if (pages[i].contains(pageNum)) {
                    return pagesBefore + pageNum - pages[i].getStart();
                } else {
                    pagesBefore += pages[i].getSize();
                }
            }

            return INVALID_PAGE_INDEX;
        }

        void startPreload(@NonNull PageRange visiblePages, @NonNull PageRange[] selectedPages,
                @NonNull PageRange[] writtenPages, RenderSpec renderSpec) {
            if (PageRangeUtils.isAllPages(selectedPages)) {
                selectedPages = new PageRange[]{new PageRange(0, mPageCount - 1)};
            }

            if (DEBUG) {
                Log.i(LOG_TAG, "Preloading pages around [" + firstShownPage
                        + "-" + lastShownPage + "]");
                Log.i(LOG_TAG, "Preloading pages around " + visiblePages + " from "
                        + Arrays.toString(selectedPages));
            }

            int firstVisiblePageIndex = findIndexOfPage(visiblePages.getStart(), selectedPages);
            int lastVisiblePageIndex = findIndexOfPage(visiblePages.getEnd(), selectedPages);

            if (firstVisiblePageIndex == INVALID_PAGE_INDEX
                    || lastVisiblePageIndex == INVALID_PAGE_INDEX) {
                return;
            }

            final int bitmapSizeInBytes = renderSpec.bitmapWidth * renderSpec.bitmapHeight
@@ -534,28 +589,33 @@ public final class PageContentRepository {
            final int maxCachedPageCount = mPageContentCache.getMaxSizeInBytes()
                    / bitmapSizeInBytes;
            final int halfPreloadCount = (maxCachedPageCount
                    - (lastShownPage - firstShownPage)) / 2 - 1;
                    - (lastVisiblePageIndex - firstVisiblePageIndex)) / 2 - 1;

            final int excessFromStart;
            if (firstShownPage - halfPreloadCount < 0) {
                excessFromStart = halfPreloadCount - firstShownPage;
            } else {
                excessFromStart = 0;
            final int fromIndex = Math.max(firstVisiblePageIndex - halfPreloadCount, 0);
            final int toIndex = lastVisiblePageIndex + halfPreloadCount;

            if (DEBUG) {
                Log.i(LOG_TAG, "fromIndex=" + fromIndex + " toIndex=" + toIndex);
            }

            final int excessFromEnd;
            if (lastShownPage + halfPreloadCount >= mPageCount) {
                excessFromEnd = (lastShownPage + halfPreloadCount) - mPageCount;
            } else {
                excessFromEnd = 0;
            int previousRangeSizes = 0;
            for (int rangeNum = 0; rangeNum < selectedPages.length; rangeNum++) {
                PageRange range = selectedPages[rangeNum];

                int thisRangeStart = Math.max(0, fromIndex - previousRangeSizes);
                int thisRangeEnd = Math.min(range.getSize(), toIndex - previousRangeSizes + 1);

                for (int i = thisRangeStart; i < thisRangeEnd; i++) {
                    if (PageRangeUtils.contains(writtenPages, range.getStart() + i)) {
                        if (DEBUG) {
                            Log.i(LOG_TAG, "Preloading " + (range.getStart() + i));
                        }

            final int fromIndex = Math.max(firstShownPage - halfPreloadCount - excessFromEnd, 0);
            final int toIndex = Math.min(lastShownPage + halfPreloadCount + excessFromStart,
                    mPageCount - 1);
                        renderPage(range.getStart() + i, renderSpec, null);
                    }
                }

            for (int i = fromIndex; i <= toIndex; i++) {
                renderPage(i, renderSpec, null);
                previousRangeSizes += range.getSize();
            }
        }

+14 −9
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.printspooler.ui;

import android.annotation.NonNull;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
@@ -24,8 +25,8 @@ import android.os.Handler;
import android.os.Looper;
import android.os.ParcelFileDescriptor;
import android.print.PageRange;
import android.print.PrintAttributes.MediaSize;
import android.print.PrintAttributes.Margins;
import android.print.PrintAttributes.MediaSize;
import android.print.PrintDocumentInfo;
import android.support.v7.widget.RecyclerView.Adapter;
import android.support.v7.widget.RecyclerView.ViewHolder;
@@ -33,11 +34,12 @@ import android.util.Log;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.MeasureSpec;
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.OpenDocumentCallback;
import com.android.printspooler.model.PageContentRepository;
@@ -45,6 +47,7 @@ import com.android.printspooler.model.PageContentRepository.PageContentProvider;
import com.android.printspooler.util.PageRangeUtils;
import com.android.printspooler.widget.PageContentView;
import com.android.printspooler.widget.PreviewPageFrame;

import dalvik.system.CloseGuard;

import java.util.ArrayList;
@@ -794,14 +797,16 @@ public final class PageAdapter extends Adapter<ViewHolder> {
        page.setTag(null);
    }

    public void startPreloadContent(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);
    void startPreloadContent(@NonNull PageRange visiblePagesInAdapter) {
        int startVisibleDocument = computePageIndexInDocument(visiblePagesInAdapter.getStart());
        int endVisibleDocument = computePageIndexInDocument(visiblePagesInAdapter.getEnd());
        if (startVisibleDocument == INVALID_PAGE_INDEX
                || endVisibleDocument == INVALID_PAGE_INDEX) {
            return;
        }

        mPageContentRepository.startPreload(new PageRange(startVisibleDocument, endVisibleDocument),
                mSelectedPages, mWrittenPages);
    }

    public void stopPreloadContent() {