0

Control PDF incremental loading with a feature

Adds a "PdfIncrementalLoading" feature to control whether or not the PDF
viewer tries to use incremental loading. The default state is enabled,
as this feature has shipped already, but we would like to experiment
with disabling it to address certain problems related to incremental
loading.

crrev.com/c/2349429 added a similar control for "partial" loading. The
two features are orthogonal: Incremental loading tries to load a PDF
before all the bytes have arrived, while partial loading tries to fetch
the bytes out of order. (Partial loading currently is not useful without
incremental loading, however.)

The linearized.pdf file was derived from the equivalent file in
third_party/pdfium/testing/resources. For the purposes of this test, the
file has been relinearized and decompressed using qpdf.

Bug: 1115149
Change-Id: Ib9f9d3d66b9c5d051528a6d49b4662b70d236649
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2352217
Commit-Queue: K. Moon <kmoon@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Reviewed-by: Daniel Hosseinian <dhoss@chromium.org>
Cr-Commit-Position: refs/heads/master@{#798225}
This commit is contained in:
K. Moon
2020-08-14 20:26:10 +00:00
committed by Commit Bot
parent 8aed8cc1b0
commit d8480c91b1
5 changed files with 49 additions and 2 deletions

@ -13,6 +13,12 @@ const base::Feature kAccessiblePDFForm = {"AccessiblePDFForm",
const base::Feature kPdfHonorJsContentSettings = {
"PdfHonorJsContentSettings", base::FEATURE_DISABLED_BY_DEFAULT};
// "Incremental loading" refers to loading the PDF as it arrives.
// TODO(crbug.com/1064175): Remove this once incremental loading is fixed.
const base::Feature kPdfIncrementalLoading = {"PdfIncrementalLoading",
base::FEATURE_ENABLED_BY_DEFAULT};
// "Partial loading" refers to loading only specific parts of the PDF.
// TODO(crbug.com/1064175): Remove this once partial loading is fixed.
const base::Feature kPdfPartialLoading = {"PdfPartialLoading",
base::FEATURE_ENABLED_BY_DEFAULT};

@ -15,6 +15,7 @@ namespace features {
extern const base::Feature kAccessiblePDFForm;
extern const base::Feature kPdfHonorJsContentSettings;
extern const base::Feature kPdfIncrementalLoading;
extern const base::Feature kPdfPartialLoading;
extern const base::Feature kPDFViewerUpdate;
extern const base::Feature kSaveEditedPDFForm;

@ -616,7 +616,8 @@ void PDFiumEngine::PostPaint() {
bool PDFiumEngine::HandleDocumentLoad(const pp::URLLoader& loader) {
password_tries_remaining_ = kMaxPasswordTries;
process_when_pending_request_complete_ = true;
process_when_pending_request_complete_ =
base::FeatureList::IsEnabled(features::kPdfIncrementalLoading);
if (!doc_loader_set_for_testing_) {
auto loader_wrapper =

@ -14,6 +14,7 @@
#include "pdf/pdfium/pdfium_page.h"
#include "pdf/pdfium/pdfium_test_base.h"
#include "pdf/test/test_client.h"
#include "pdf/test/test_document_loader.h"
#include "pdf/test/test_utils.h"
#include "ppapi/c/ppb_input_event.h"
#include "ppapi/cpp/size.h"
@ -22,6 +23,7 @@
#include "ui/gfx/geometry/size.h"
namespace chrome_pdf {
namespace {
using ::testing::InSequence;
@ -55,6 +57,8 @@ class MockTestClient : public TestClient {
MOCK_METHOD(void, ScrollToPage, (int page), (override));
};
} // namespace
class PDFiumEngineTest : public PDFiumTestBase {
protected:
void ExpectPageRect(PDFiumEngine* engine,
@ -64,6 +68,27 @@ class PDFiumEngineTest : public PDFiumTestBase {
ASSERT_TRUE(page);
CompareRect(expected_rect, page->rect());
}
// Tries to load a PDF incrementally, returning `true` on success.
bool TryLoadIncrementally() {
NiceMock<MockTestClient> client;
InitializeEngineResult initialize_result = InitializeEngineWithoutLoading(
&client, FILE_PATH_LITERAL("linearized.pdf"));
if (!initialize_result.engine) {
ADD_FAILURE();
return false;
}
PDFiumEngine* engine = initialize_result.engine.get();
// Note: Plugin size chosen so all pages of the document are visible. The
// engine only updates availability incrementally for visible pages.
engine->PluginSizeUpdated({1024, 4096});
initialize_result.document_loader->SimulateLoadData(8192);
PDFiumPage* page0 = GetPDFiumPageForTest(engine, 0);
PDFiumPage* page1 = GetPDFiumPageForTest(engine, 1);
return page0 && page0->available() && page1 && !page1->available();
}
};
TEST_F(PDFiumEngineTest, InitializeWithRectanglesMultiPagesPdf) {
@ -302,7 +327,21 @@ TEST_F(PDFiumEngineTest, GetBadPdfVersion) {
EXPECT_EQ(PdfVersion::kUnknown, doc_metadata.version);
}
} // namespace
TEST_F(PDFiumEngineTest, IncrementalLoadingFeatureDefault) {
EXPECT_TRUE(TryLoadIncrementally());
}
TEST_F(PDFiumEngineTest, IncrementalLoadingFeatureEnabled) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeature(features::kPdfIncrementalLoading);
EXPECT_TRUE(TryLoadIncrementally());
}
TEST_F(PDFiumEngineTest, IncrementalLoadingFeatureDisabled) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndDisableFeature(features::kPdfIncrementalLoading);
EXPECT_FALSE(TryLoadIncrementally());
}
class TabbingTestClient : public TestClient {
public:

Binary file not shown.