diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-08-28 15:28:34 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-08-28 13:54:51 +0000 |
commit | 2a19c63448c84c1805fb1a585c3651318bb86ca7 (patch) | |
tree | eb17888e8531aa6ee5e85721bd553b832a7e5156 /chromium/pdf | |
parent | b014812705fc80bff0a5c120dfcef88f349816dc (diff) | |
download | qtwebengine-chromium-2a19c63448c84c1805fb1a585c3651318bb86ca7.tar.gz |
BASELINE: Update Chromium to 69.0.3497.70
Change-Id: I2b7b56e4e7a8b26656930def0d4575dc32b900a0
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/pdf')
29 files changed, 823 insertions, 550 deletions
diff --git a/chromium/pdf/BUILD.gn b/chromium/pdf/BUILD.gn index b4350b56a76..ee973f481ac 100644 --- a/chromium/pdf/BUILD.gn +++ b/chromium/pdf/BUILD.gn @@ -8,6 +8,7 @@ import("//build/config/jumbo.gni") import("//pdf/features.gni") import("//testing/test.gni") import("//third_party/pdfium/pdfium.gni") +import("//v8/gni/v8.gni") # Generate a buildflag header for compile-time checking of PDF support. buildflag_header("buildflags") { @@ -59,8 +60,6 @@ if (enable_pdf) { "preview_mode_client.h", "range_set.cc", "range_set.h", - "timer.cc", - "timer.h", "url_loader_wrapper.h", "url_loader_wrapper_impl.cc", "url_loader_wrapper_impl.h", @@ -80,6 +79,8 @@ if (enable_pdf) { "pdfium/pdfium_api_string_buffer_adapter.cc", "pdfium/pdfium_api_string_buffer_adapter.h", "pdfium/pdfium_assert_matching_enums.cc", + "pdfium/pdfium_document.cc", + "pdfium/pdfium_document.h", "pdfium/pdfium_engine.cc", "pdfium/pdfium_engine.h", "pdfium/pdfium_engine_exports.cc", @@ -96,6 +97,8 @@ if (enable_pdf) { "pdfium/pdfium_print.h", "pdfium/pdfium_range.cc", "pdfium/pdfium_range.h", + "pdfium/pdfium_unsupported_features.cc", + "pdfium/pdfium_unsupported_features.h", ] include_dirs += [ "//third_party/pdfium" ] @@ -132,8 +135,19 @@ if (enable_pdf) { ] if (pdf_engine == 0) { - sources += [ "pdfium/findtext_unittest.cc" ] + configs += [ "//v8:external_startup_data" ] + sources += [ + "pdfium/findtext_unittest.cc", + "pdfium/pdfium_engine_exports_unittest.cc", + ] include_dirs = [ "//third_party/pdfium" ] + + if (v8_use_external_startup_data) { + data += [ + "$root_out_dir/natives_blob.bin", + "$root_out_dir/snapshot_blob.bin", + ] + } } } } else { diff --git a/chromium/pdf/chunk_stream.h b/chromium/pdf/chunk_stream.h index 7eb75cf61b8..7fc092e1ed5 100644 --- a/chromium/pdf/chunk_stream.h +++ b/chromium/pdf/chunk_stream.h @@ -81,6 +81,10 @@ class ChunkStream { return filled_chunks_.Contains(chunks_range); } + bool IsChunkAvailable(uint32_t chunk_index) const { + return filled_chunks_.Contains(chunk_index); + } + void set_eof_pos(uint32_t eof_pos) { eof_pos_ = eof_pos; } uint32_t eof_pos() const { return eof_pos_; } @@ -90,6 +94,10 @@ class ChunkStream { return eof_pos_ > 0 && IsRangeAvailable(gfx::Range(0, eof_pos_)); } + bool IsValidChunkIndex(uint32_t chunk_index) const { + return !eof_pos_ || (chunk_index <= GetChunkIndex(eof_pos_ - 1)); + } + void Clear() { data_.clear(); eof_pos_ = 0; diff --git a/chromium/pdf/document_loader_impl.cc b/chromium/pdf/document_loader_impl.cc index a951f9d2874..f28121815c8 100644 --- a/chromium/pdf/document_loader_impl.cc +++ b/chromium/pdf/document_loader_impl.cc @@ -204,8 +204,16 @@ void DocumentLoaderImpl::SetPartialLoadingEnabled(bool enabled) { bool DocumentLoaderImpl::ShouldCancelLoading() const { if (!loader_) return true; - if (!partial_loading_enabled_ || pending_requests_.IsEmpty()) + + if (!partial_loading_enabled_) return false; + + if (pending_requests_.IsEmpty()) { + // Cancel loading if this is unepected data from server. + return !chunk_stream_.IsValidChunkIndex(chunk_.chunk_index) || + chunk_stream_.IsChunkAvailable(chunk_.chunk_index); + } + const gfx::Range current_range(chunk_.chunk_index, chunk_.chunk_index + kChunkCloseDistance); return !pending_requests_.Intersects(current_range); @@ -328,11 +336,6 @@ void DocumentLoaderImpl::DidRead(int32_t result) { bool DocumentLoaderImpl::SaveBuffer(char* input, uint32_t input_size) { const uint32_t document_size = GetDocumentSize(); - if (document_size != 0) { - // If the HTTP server sends more data than expected, then truncate - // |input_size| to the expected size. - input_size = std::min(document_size - bytes_received_, input_size); - } bytes_received_ += input_size; bool chunk_saved = false; bool loading_pending_request = pending_requests_.Contains(chunk_.chunk_index); @@ -346,7 +349,7 @@ bool DocumentLoaderImpl::SaveBuffer(char* input, uint32_t input_size) { new_chunk_data_len); chunk_.data_size += new_chunk_data_len; if (chunk_.data_size == DataStream::kChunkSize || - document_size == EndOfCurrentChunk()) { + (document_size > 0 && document_size <= EndOfCurrentChunk())) { pending_requests_.Subtract( gfx::Range(chunk_.chunk_index, chunk_.chunk_index + 1)); SaveChunkData(); diff --git a/chromium/pdf/document_loader_impl_unittest.cc b/chromium/pdf/document_loader_impl_unittest.cc index 682e89996bc..0595e049503 100644 --- a/chromium/pdf/document_loader_impl_unittest.cc +++ b/chromium/pdf/document_loader_impl_unittest.cc @@ -1068,4 +1068,99 @@ TEST_F(DocumentLoaderImplTest, Mock::VerifyAndClear(&client); } +TEST_F(DocumentLoaderImplTest, IgnoreDataMoreThanExpectedWithPartial) { + static constexpr uint32_t kDocSize = kDefaultRequestSize * 80 - 321; + TestClient client; + client.SetCanUsePartialLoading(); + client.full_page_loader_data()->set_content_length(kDocSize); + DocumentLoaderImpl loader(&client); + loader.Init(client.CreateFullPageLoader(), "http://url.com"); + // Request data at and. + loader.RequestData(kDocSize - 100, 100); + + // Always send initial data from FullPageLoader. + client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize); + EXPECT_TRUE(client.full_page_loader_data()->closed()); + EXPECT_FALSE(client.partial_loader_data()->closed()); + + // Request data at middle to continue loading partial, but not all remaining + // data. + loader.RequestData(kDocSize / 2, 100); + + // Fill data at the end, the partial loding should be started for second + // requested data after receive data for first request. + client.SendAllPartialData(); + + ASSERT_TRUE(client.partial_loader_data()->IsWaitOpen()); + // Process second request. + const uint32_t expected_length = + client.partial_loader_data()->open_byte_range().length(); + + // Send data. + client.partial_loader_data()->set_byte_range( + client.partial_loader_data()->open_byte_range()); + client.partial_loader_data()->CallOpenCallback(0); + uint32_t length = expected_length; + while (length > 0) { + const uint32_t max_part_len = kDefaultRequestSize; + const uint32_t part_len = std::min(length, max_part_len); + client.partial_loader_data()->CallReadCallback(part_len); + length -= part_len; + } + + // The partial loading should be finished for current chunks sequence, if + // expected range was received, and remaining sequence should start loading. + EXPECT_FALSE(client.partial_loader_data()->IsWaitRead()); + ASSERT_TRUE(client.partial_loader_data()->IsWaitOpen()); + + // Send other document data. + client.SendAllPartialData(); + // The downloads should be finished. + EXPECT_TRUE(client.full_page_loader_data()->closed()); + EXPECT_TRUE(client.partial_loader_data()->closed()); +} + +TEST_F(DocumentLoaderImplTest, IgnoreDataMoreThanExpectedWithPartialAtFileEnd) { + static constexpr uint32_t kExtraSize = 100; + static constexpr uint32_t kRealSize = kDefaultRequestSize * 20 - 300; + static constexpr uint32_t kDocSize = kRealSize - kExtraSize; + TestClient client; + client.SetCanUsePartialLoading(); + client.full_page_loader_data()->set_content_length(kDocSize); + DocumentLoaderImpl loader(&client); + loader.Init(client.CreateFullPageLoader(), "http://url.com"); + // Request data at middle. + static constexpr uint32_t kFirstPartial = kDefaultRequestSize * 11; + loader.RequestData(kFirstPartial, kDefaultRequestSize); + + // Always send initial data from FullPageLoader. + client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize); + EXPECT_TRUE(client.full_page_loader_data()->closed()); + EXPECT_FALSE(client.partial_loader_data()->closed()); + + // Send data to file end and extra non expected data. + client.partial_loader_data()->set_byte_range( + gfx::Range(kFirstPartial, kRealSize)); + client.partial_loader_data()->CallOpenCallback(0); + uint32_t length = client.partial_loader_data()->byte_range().length(); + while (length > 0) { + const uint32_t max_part_len = kDefaultRequestSize; + const uint32_t part_len = std::min(length, max_part_len); + client.partial_loader_data()->CallReadCallback(part_len); + length -= part_len; + } + + // The partial loading should be finished for current chunks sequence, if + // eof was reached, and remaining sequence should start loading. + EXPECT_FALSE(client.partial_loader_data()->IsWaitRead()); + EXPECT_EQ(gfx::Range(kDefaultRequestSize, kFirstPartial), + client.partial_loader_data()->open_byte_range()); + + // Send other document data. + client.SendAllPartialData(); + // The downloads should be finished. + EXPECT_TRUE(client.full_page_loader_data()->closed()); + EXPECT_TRUE(client.partial_loader_data()->closed()); +} + } // namespace chrome_pdf diff --git a/chromium/pdf/out_of_process_instance.cc b/chromium/pdf/out_of_process_instance.cc index 8486db85360..0358d15fb45 100644 --- a/chromium/pdf/out_of_process_instance.cc +++ b/chromium/pdf/out_of_process_instance.cc @@ -471,6 +471,7 @@ bool OutOfProcessInstance::Init(uint32_t argc, text_input_ = std::make_unique<pp::TextInput_Dev>(this); + bool enable_javascript = false; const char* stream_url = nullptr; const char* original_url = nullptr; const char* top_level_url = nullptr; @@ -490,6 +491,8 @@ bool OutOfProcessInstance::Init(uint32_t argc, } else if (strcmp(argn[i], "top-toolbar-height") == 0) { success = base::StringToInt(argv[i], &top_toolbar_height_in_viewport_coords_); + } else if (strcmp(argn[i], "javascript") == 0) { + enable_javascript = (strcmp(argv[i], "allow") == 0); } if (!success) return false; @@ -501,7 +504,10 @@ bool OutOfProcessInstance::Init(uint32_t argc, if (!stream_url) stream_url = original_url; - engine_ = PDFEngine::Create(this, true); + if (!engine_) { + // TODO(tsepez): fix lifetime issue, conditionalize javascript. + engine_ = PDFEngine::Create(this, true); + } // If we're in print preview mode we don't need to load the document yet. // A |kJSResetPrintPreviewModeType| message will be sent to the plugin letting @@ -1232,14 +1238,6 @@ void OutOfProcessInstance::DidOpenPreview(int32_t result) { } } -void OutOfProcessInstance::OnClientTouchTimerFired(int32_t id) { - engine_->OnTouchTimerCallback(id); -} - -void OutOfProcessInstance::OnClientTimerFired(int32_t id) { - engine_->OnCallback(id); -} - void OutOfProcessInstance::CalculateBackgroundParts() { background_parts_.clear(); int left_width = available_area_.x(); @@ -1542,7 +1540,7 @@ void OutOfProcessInstance::SubmitForm(const std::string& url, void OutOfProcessInstance::FormDidOpen(int32_t result) { // TODO: inform the user of success/failure. if (result != PP_OK) { - NOTREACHED(); + LOG(ERROR) << "FormDidOpen failed: " << result; } } @@ -1563,21 +1561,6 @@ pp::URLLoader OutOfProcessInstance::CreateURLLoader() { return CreateURLLoaderInternal(); } -void OutOfProcessInstance::ScheduleCallback(int id, base::TimeDelta delay) { - pp::CompletionCallback callback = - callback_factory_.NewCallback(&OutOfProcessInstance::OnClientTimerFired); - pp::Module::Get()->core()->CallOnMainThread(delay.InMilliseconds(), callback, - id); -} - -void OutOfProcessInstance::ScheduleTouchTimerCallback(int id, - base::TimeDelta delay) { - pp::CompletionCallback callback = callback_factory_.NewCallback( - &OutOfProcessInstance::OnClientTouchTimerFired); - pp::Module::Get()->core()->CallOnMainThread(delay.InMilliseconds(), callback, - id); -} - std::vector<PDFEngine::Client::SearchStringResult> OutOfProcessInstance::SearchString(const base::char16* string, const base::char16* term, @@ -1758,6 +1741,7 @@ pp::Instance* OutOfProcessInstance::GetPluginInstance() { void OutOfProcessInstance::DocumentHasUnsupportedFeature( const std::string& feature) { + DCHECK(!feature.empty()); std::string metric("PDF_Unsupported_"); metric += feature; if (!unsupported_features_reported_.count(metric)) { diff --git a/chromium/pdf/out_of_process_instance.h b/chromium/pdf/out_of_process_instance.h index 5df898569aa..18ce4321f15 100644 --- a/chromium/pdf/out_of_process_instance.h +++ b/chromium/pdf/out_of_process_instance.h @@ -95,10 +95,6 @@ class OutOfProcessInstance : public pp::Instance, void DidOpen(int32_t result); void DidOpenPreview(int32_t result); - // Called when the timer is fired. - void OnClientTimerFired(int32_t id); - void OnClientTouchTimerFired(int32_t id); - // Called to print without re-entrancy issues. void OnPrint(int32_t); @@ -136,8 +132,6 @@ class OutOfProcessInstance : public pp::Instance, const void* data, int length) override; pp::URLLoader CreateURLLoader() override; - void ScheduleCallback(int id, base::TimeDelta delay) override; - void ScheduleTouchTimerCallback(int id, base::TimeDelta delay) override; std::vector<SearchStringResult> SearchString(const base::char16* string, const base::char16* term, bool case_sensitive) override; diff --git a/chromium/pdf/pdf.cc b/chromium/pdf/pdf.cc index e4583f5250a..208e5e781ee 100644 --- a/chromium/pdf/pdf.cc +++ b/chromium/pdf/pdf.cc @@ -11,11 +11,43 @@ #endif #include "base/logging.h" +#include "base/macros.h" #include "pdf/out_of_process_instance.h" #include "pdf/pdf_ppapi.h" namespace chrome_pdf { +namespace { + +class ScopedSdkInitializer { + public: + ScopedSdkInitializer() {} + ~ScopedSdkInitializer() { +#if DCHECK_IS_ON() + DCHECK(initialized_); +#endif + if (!IsSDKInitializedViaPepper()) + ShutdownSDK(); + } + + // Must be called. + bool Init() { +#if DCHECK_IS_ON() + initialized_ = true; +#endif + return IsSDKInitializedViaPepper() || InitializeSDK(); + } + + private: +#if DCHECK_IS_ON() + bool initialized_ = false; +#endif + + DISALLOW_COPY_AND_ASSIGN(ScopedSdkInitializer); +}; + +} // namespace + #if defined(OS_WIN) bool RenderPDFPageToDC(const void* pdf_buffer, int buffer_size, @@ -33,23 +65,18 @@ bool RenderPDFPageToDC(const void* pdf_buffer, bool center_in_bounds, bool autorotate, bool use_color) { - if (!IsSDKInitializedViaPepper()) { - if (!InitializeSDK()) { - return false; - } - } + ScopedSdkInitializer scoped_sdk_initializer; + if (!scoped_sdk_initializer.Init()) + return false; + PDFEngineExports* engine_exports = PDFEngineExports::Get(); PDFEngineExports::RenderingSettings settings( dpi_x, dpi_y, pp::Rect(bounds_origin_x, bounds_origin_y, bounds_width, bounds_height), fit_to_bounds, stretch_to_bounds, keep_aspect_ratio, center_in_bounds, autorotate, use_color); - bool ret = engine_exports->RenderPDFPageToDC(pdf_buffer, buffer_size, - page_number, settings, dc); - if (!IsSDKInitializedViaPepper()) - ShutdownSDK(); - - return ret; + return engine_exports->RenderPDFPageToDC(pdf_buffer, buffer_size, page_number, + settings, dc); } void SetPDFEnsureTypefaceCharactersAccessible( @@ -70,17 +97,13 @@ bool GetPDFDocInfo(const void* pdf_buffer, int buffer_size, int* page_count, double* max_page_width) { - if (!IsSDKInitializedViaPepper()) { - if (!InitializeSDK()) - return false; - } - PDFEngineExports* engine_exports = PDFEngineExports::Get(); - bool ret = engine_exports->GetPDFDocInfo(pdf_buffer, buffer_size, page_count, - max_page_width); - if (!IsSDKInitializedViaPepper()) - ShutdownSDK(); + ScopedSdkInitializer scoped_sdk_initializer; + if (!scoped_sdk_initializer.Init()) + return false; - return ret; + PDFEngineExports* engine_exports = PDFEngineExports::Get(); + return engine_exports->GetPDFDocInfo(pdf_buffer, buffer_size, page_count, + max_page_width); } bool GetPDFPageSizeByIndex(const void* pdf_buffer, @@ -88,17 +111,14 @@ bool GetPDFPageSizeByIndex(const void* pdf_buffer, int page_number, double* width, double* height) { - if (!IsSDKInitializedViaPepper()) { - if (!chrome_pdf::InitializeSDK()) - return false; - } + ScopedSdkInitializer scoped_sdk_initializer; + if (!scoped_sdk_initializer.Init()) + return false; + chrome_pdf::PDFEngineExports* engine_exports = chrome_pdf::PDFEngineExports::Get(); - bool ret = engine_exports->GetPDFPageSizeByIndex(pdf_buffer, pdf_buffer_size, - page_number, width, height); - if (!IsSDKInitializedViaPepper()) - chrome_pdf::ShutdownSDK(); - return ret; + return engine_exports->GetPDFPageSizeByIndex(pdf_buffer, pdf_buffer_size, + page_number, width, height); } bool RenderPDFPageToBitmap(const void* pdf_buffer, @@ -111,20 +131,16 @@ bool RenderPDFPageToBitmap(const void* pdf_buffer, int dpi_y, bool autorotate, bool use_color) { - if (!IsSDKInitializedViaPepper()) { - if (!InitializeSDK()) - return false; - } + ScopedSdkInitializer scoped_sdk_initializer; + if (!scoped_sdk_initializer.Init()) + return false; + PDFEngineExports* engine_exports = PDFEngineExports::Get(); PDFEngineExports::RenderingSettings settings( dpi_x, dpi_y, pp::Rect(bitmap_width, bitmap_height), true, false, true, true, autorotate, use_color); - bool ret = engine_exports->RenderPDFPageToBitmap( + return engine_exports->RenderPDFPageToBitmap( pdf_buffer, pdf_buffer_size, page_number, settings, bitmap_buffer); - if (!IsSDKInitializedViaPepper()) - ShutdownSDK(); - - return ret; } } // namespace chrome_pdf diff --git a/chromium/pdf/pdf_engine.h b/chromium/pdf/pdf_engine.h index 88d8e3fe22a..b8be4541a16 100644 --- a/chromium/pdf/pdf_engine.h +++ b/chromium/pdf/pdf_engine.h @@ -219,12 +219,6 @@ class PDFEngine { // Creates and returns new URL loader for partial document requests. virtual pp::URLLoader CreateURLLoader() = 0; - // Calls the client's OnCallback() function in |delay| with the given |id|. - virtual void ScheduleCallback(int id, base::TimeDelta delay) {} - // Calls the client's OnTouchTimerCallback() function in |delay| with the - // given |id|. - virtual void ScheduleTouchTimerCallback(int id, base::TimeDelta delay) {} - // Searches the given string for "term" and returns the results. Unicode- // aware. struct SearchStringResult { @@ -363,10 +357,6 @@ class PDFEngine { virtual int GetVerticalScrollbarYPosition() = 0; // Set color / grayscale rendering modes. virtual void SetGrayscale(bool grayscale) = 0; - // Callback for timer that's set with ScheduleCallback(). - virtual void OnCallback(int id) = 0; - // Callback for timer that's set with ScheduleTouchTimerCallback(). - virtual void OnTouchTimerCallback(int id) = 0; // Get the number of characters on a given page. virtual int GetCharCount(int page_index) = 0; // Get the bounds in page pixels of a character on a given page. @@ -406,13 +396,6 @@ class PDFEngine { // document at page |index|. virtual void AppendPage(PDFEngine* engine, int index) = 0; -#if defined(PDF_ENABLE_XFA) - // Allow client to set scroll positions in document coordinates. Note that - // this is meant for cases where the device scale factor changes, and not for - // general scrolling - the engine will not repaint due to this. - virtual void SetScrollPosition(const pp::Point& position) = 0; -#endif - virtual std::string GetMetadata(const std::string& key) = 0; virtual void SetCaretPosition(const pp::Point& position) = 0; diff --git a/chromium/pdf/pdfium/DEPS b/chromium/pdf/pdfium/DEPS index 5e8aa4cb995..f157a81c75d 100644 --- a/chromium/pdf/pdfium/DEPS +++ b/chromium/pdf/pdfium/DEPS @@ -1,6 +1,7 @@ include_rules = [ "+gin/array_buffer.h", "+gin/public", + "+gin/v8_initializer.h", "+printing/nup_parameters.h", "+third_party/pdfium/public", "+ui/gfx/codec/jpeg_codec.h", diff --git a/chromium/pdf/pdfium/fuzzers/BUILD.gn b/chromium/pdf/pdfium/fuzzers/BUILD.gn index 82fd8eba64a..ffac41d48fc 100644 --- a/chromium/pdf/pdfium/fuzzers/BUILD.gn +++ b/chromium/pdf/pdfium/fuzzers/BUILD.gn @@ -3,11 +3,12 @@ # found in the LICENSE file. # PDFium fuzzers. -# When adding a fuzzer_test target make sure to add it to the group 'pdf_fuzzers' +# When adding a fuzzer_test target make sure to add it to the group +# 'pdf_fuzzers' -import("//third_party/pdfium/pdfium.gni") import("//testing/test.gni") import("//testing/libfuzzer/fuzzer_test.gni") +import("//third_party/pdfium/pdfium.gni") group("fuzzers") { } @@ -80,35 +81,35 @@ fuzzer_test("pdfium_fuzzer") { fuzzer_test("pdf_cmap_fuzzer") { sources = [] deps = [ - "//third_party/pdfium/testing/libfuzzer:pdf_cmap_fuzzer", + "//third_party/pdfium/testing/fuzzers:pdf_cmap_fuzzer_src", ] } fuzzer_test("pdf_codec_a85_fuzzer") { sources = [] deps = [ - "//third_party/pdfium/testing/libfuzzer:pdf_codec_a85_fuzzer", + "//third_party/pdfium/testing/fuzzers:pdf_codec_a85_fuzzer_src", ] } fuzzer_test("pdf_codec_fax_fuzzer") { sources = [] deps = [ - "//third_party/pdfium/testing/libfuzzer:pdf_codec_fax_fuzzer", + "//third_party/pdfium/testing/fuzzers:pdf_codec_fax_fuzzer_src", ] } fuzzer_test("pdf_codec_rle_fuzzer") { sources = [] deps = [ - "//third_party/pdfium/testing/libfuzzer:pdf_codec_rle_fuzzer", + "//third_party/pdfium/testing/fuzzers:pdf_codec_rle_fuzzer_src", ] } fuzzer_test("pdf_codec_icc_fuzzer") { sources = [] deps = [ - "//third_party/pdfium/testing/libfuzzer:pdf_codec_icc_fuzzer", + "//third_party/pdfium/testing/fuzzers:pdf_codec_icc_fuzzer_src", ] dict = "dicts/pdf_codec_icc.dict" } @@ -116,21 +117,21 @@ fuzzer_test("pdf_codec_icc_fuzzer") { fuzzer_test("pdf_codec_jbig2_fuzzer") { sources = [] deps = [ - "//third_party/pdfium/testing/libfuzzer:pdf_codec_jbig2_fuzzer", + "//third_party/pdfium/testing/fuzzers:pdf_codec_jbig2_fuzzer_src", ] } fuzzer_test("pdf_hint_table_fuzzer") { sources = [] deps = [ - "//third_party/pdfium/testing/libfuzzer:pdf_hint_table_fuzzer", + "//third_party/pdfium/testing/fuzzers:pdf_hint_table_fuzzer_src", ] } fuzzer_test("pdf_jpx_fuzzer") { sources = [] deps = [ - "//third_party/pdfium/testing/libfuzzer:pdf_jpx_fuzzer", + "//third_party/pdfium/testing/fuzzers:pdf_jpx_fuzzer_src", ] seed_corpus = "corpora/pdf_jpx" } @@ -138,21 +139,21 @@ fuzzer_test("pdf_jpx_fuzzer") { fuzzer_test("pdf_font_fuzzer") { sources = [] deps = [ - "//third_party/pdfium/testing/libfuzzer:pdf_font_fuzzer", + "//third_party/pdfium/testing/fuzzers:pdf_font_fuzzer_src", ] } fuzzer_test("pdf_psengine_fuzzer") { sources = [] deps = [ - "//third_party/pdfium/testing/libfuzzer:pdf_psengine_fuzzer", + "//third_party/pdfium/testing/fuzzers:pdf_psengine_fuzzer_src", ] } fuzzer_test("pdf_streamparser_fuzzer") { sources = [] deps = [ - "//third_party/pdfium/testing/libfuzzer:pdf_streamparser_fuzzer", + "//third_party/pdfium/testing/fuzzers:pdf_streamparser_fuzzer_src", ] } @@ -161,7 +162,7 @@ if (pdf_enable_xfa) { fuzzer_test("pdf_codec_bmp_fuzzer") { sources = [] deps = [ - "//third_party/pdfium/testing/libfuzzer:pdf_codec_bmp_fuzzer", + "//third_party/pdfium/testing/fuzzers:pdf_codec_bmp_fuzzer_src", ] seed_corpus = "corpora/pdf_codec_bmp" } @@ -171,7 +172,7 @@ if (pdf_enable_xfa) { fuzzer_test("pdf_codec_gif_fuzzer") { sources = [] deps = [ - "//third_party/pdfium/testing/libfuzzer:pdf_codec_gif_fuzzer", + "//third_party/pdfium/testing/fuzzers:pdf_codec_gif_fuzzer_src", ] dict = "dicts/pdf_codec_gif.dict" seed_corpus = "corpora/pdf_codec_gif" @@ -181,7 +182,7 @@ if (pdf_enable_xfa) { fuzzer_test("pdf_codec_jpeg_fuzzer") { sources = [] deps = [ - "//third_party/pdfium/testing/libfuzzer:pdf_codec_jpeg_fuzzer", + "//third_party/pdfium/testing/fuzzers:pdf_codec_jpeg_fuzzer_src", ] dict = "dicts/pdf_codec_jpeg.dict" seed_corpus = "corpora/pdf_codec_jpeg" @@ -191,7 +192,7 @@ if (pdf_enable_xfa) { fuzzer_test("pdf_codec_png_fuzzer") { sources = [] deps = [ - "//third_party/pdfium/testing/libfuzzer:pdf_codec_png_fuzzer", + "//third_party/pdfium/testing/fuzzers:pdf_codec_png_fuzzer_src", ] dict = "dicts/pdf_codec_png.dict" seed_corpuses = [ @@ -207,7 +208,7 @@ if (pdf_enable_xfa) { fuzzer_test("pdf_codec_tiff_fuzzer") { sources = [] deps = [ - "//third_party/pdfium/testing/libfuzzer:pdf_codec_tiff_fuzzer", + "//third_party/pdfium/testing/fuzzers:pdf_codec_tiff_fuzzer_src", ] dict = "dicts/pdf_codec_tiff.dict" seed_corpus = "corpora/pdf_codec_tiff" @@ -217,7 +218,7 @@ if (pdf_enable_xfa) { fuzzer_test("pdf_css_fuzzer") { sources = [] deps = [ - "//third_party/pdfium/testing/libfuzzer:pdf_css_fuzzer", + "//third_party/pdfium/testing/fuzzers:pdf_css_fuzzer_src", ] dict = "dicts/pdf_css.dict" } @@ -225,7 +226,7 @@ if (pdf_enable_xfa) { fuzzer_test("pdf_fm2js_fuzzer") { sources = [] deps = [ - "//third_party/pdfium/testing/libfuzzer:pdf_fm2js_fuzzer", + "//third_party/pdfium/testing/fuzzers:pdf_fm2js_fuzzer_src", ] dict = "dicts/pdf_formcalc.dict" } @@ -233,7 +234,7 @@ if (pdf_enable_xfa) { fuzzer_test("pdf_formcalc_fuzzer") { sources = [] deps = [ - "//third_party/pdfium/testing/libfuzzer:pdf_formcalc_fuzzer", + "//third_party/pdfium/testing/fuzzers:pdf_formcalc_fuzzer_src", ] dict = "dicts/pdf_formcalc.dict" } @@ -242,7 +243,7 @@ if (pdf_enable_xfa) { fuzzer_test("pdf_lzw_fuzzer") { sources = [] deps = [ - "//third_party/pdfium/testing/libfuzzer:pdf_lzw_fuzzer", + "//third_party/pdfium/testing/fuzzers:pdf_lzw_fuzzer_src", ] } } @@ -250,7 +251,7 @@ if (pdf_enable_xfa) { fuzzer_test("pdf_xml_fuzzer") { sources = [] deps = [ - "//third_party/pdfium/testing/libfuzzer:pdf_xml_fuzzer", + "//third_party/pdfium/testing/fuzzers:pdf_xml_fuzzer_src", ] dict = "dicts/pdf_xml.dict" } @@ -258,14 +259,14 @@ if (pdf_enable_xfa) { fuzzer_test("pdf_bidi_fuzzer") { sources = [] deps = [ - "//third_party/pdfium/testing/libfuzzer:pdf_bidi_fuzzer", + "//third_party/pdfium/testing/fuzzers:pdf_bidi_fuzzer_src", ] } fuzzer_test("pdf_cfx_barcode_fuzzer") { sources = [] deps = [ - "//third_party/pdfium/testing/libfuzzer:pdf_cfx_barcode_fuzzer", + "//third_party/pdfium/testing/fuzzers:pdf_cfx_barcode_fuzzer_src", ] } diff --git a/chromium/pdf/pdfium/pdfium_document.cc b/chromium/pdf/pdfium/pdfium_document.cc new file mode 100644 index 00000000000..ff6dc27b561 --- /dev/null +++ b/chromium/pdf/pdfium/pdfium_document.cc @@ -0,0 +1,116 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "pdf/pdfium/pdfium_document.h" + +#include <utility> + +#include "base/logging.h" +#include "pdf/document_loader.h" + +namespace chrome_pdf { + +namespace { + +class FileAvail : public FX_FILEAVAIL { + public: + explicit FileAvail(DocumentLoader* doc_loader) : doc_loader_(doc_loader) { + DCHECK(doc_loader); + version = 1; + IsDataAvail = &FileAvail::IsDataAvailImpl; + } + + private: + // PDFium interface to check is block of data is available. + static FPDF_BOOL IsDataAvailImpl(FX_FILEAVAIL* param, + size_t offset, + size_t size) { + auto* file_avail = static_cast<FileAvail*>(param); + return file_avail->doc_loader_->IsDataAvailable(offset, size); + } + + DocumentLoader* doc_loader_; +}; + +class DownloadHints : public FX_DOWNLOADHINTS { + public: + explicit DownloadHints(DocumentLoader* doc_loader) : doc_loader_(doc_loader) { + DCHECK(doc_loader); + version = 1; + AddSegment = &DownloadHints::AddSegmentImpl; + } + + private: + // PDFium interface to request download of the block of data. + static void AddSegmentImpl(FX_DOWNLOADHINTS* param, + size_t offset, + size_t size) { + auto* download_hints = static_cast<DownloadHints*>(param); + return download_hints->doc_loader_->RequestData(offset, size); + } + + DocumentLoader* doc_loader_; +}; + +class FileAccess : public FPDF_FILEACCESS { + public: + explicit FileAccess(DocumentLoader* doc_loader) : doc_loader_(doc_loader) { + DCHECK(doc_loader); + m_FileLen = 0; + m_GetBlock = &FileAccess::GetBlockImpl; + m_Param = this; + } + + private: + // PDFium interface to get block of data. + static int GetBlockImpl(void* param, + unsigned long position, + unsigned char* buffer, + unsigned long size) { + auto* file_access = static_cast<FileAccess*>(param); + return file_access->doc_loader_->GetBlock(position, size, buffer); + } + + DocumentLoader* doc_loader_; +}; + +} // namespace + +PDFiumDocument::PDFiumDocument(DocumentLoader* doc_loader) + : doc_loader_(doc_loader), + file_access_(std::make_unique<FileAccess>(doc_loader)), + file_availability_(std::make_unique<FileAvail>(doc_loader)), + download_hints_(std::make_unique<DownloadHints>(doc_loader)) {} + +PDFiumDocument::~PDFiumDocument() = default; + +void PDFiumDocument::CreateFPDFAvailability() { + fpdf_availability_.reset( + FPDFAvail_Create(file_availability_.get(), file_access_.get())); +} + +void PDFiumDocument::ResetFPDFAvailability() { + fpdf_availability_.reset(); +} + +void PDFiumDocument::LoadDocument(const char* password) { + if (doc_loader_->IsDocumentComplete() && + !FPDFAvail_IsLinearized(fpdf_availability_.get())) { + doc_handle_.reset(FPDF_LoadCustomDocument(file_access_.get(), password)); + } else { + doc_handle_.reset( + FPDFAvail_GetDocument(fpdf_availability_.get(), password)); + } +} + +void PDFiumDocument::SetFormStatus() { + form_status_ = + FPDFAvail_IsFormAvail(fpdf_availability_.get(), download_hints_.get()); +} + +void PDFiumDocument::InitializeForm(FPDF_FORMFILLINFO* form_info) { + form_handle_.reset(FPDFDOC_InitFormFillEnvironment(doc(), form_info)); +} + +} // namespace chrome_pdf diff --git a/chromium/pdf/pdfium/pdfium_document.h b/chromium/pdf/pdfium/pdfium_document.h new file mode 100644 index 00000000000..a5cebaca3ca --- /dev/null +++ b/chromium/pdf/pdfium/pdfium_document.h @@ -0,0 +1,71 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PDF_PDFIUM_PDFIUM_DOCUMENT_H_ +#define PDF_PDFIUM_PDFIUM_DOCUMENT_H_ + +#include "base/macros.h" +#include "third_party/pdfium/public/cpp/fpdf_scopers.h" +#include "third_party/pdfium/public/fpdf_dataavail.h" +#include "third_party/pdfium/public/fpdfview.h" + +namespace chrome_pdf { + +class DocumentLoader; + +class PDFiumDocument { + public: + explicit PDFiumDocument(DocumentLoader* doc_loader); + ~PDFiumDocument(); + + FPDF_FILEACCESS& file_access() { return *file_access_; } + FX_FILEAVAIL& file_availability() { return *file_availability_; } + FX_DOWNLOADHINTS& download_hints() { return *download_hints_; } + + FPDF_AVAIL fpdf_availability() const { return fpdf_availability_.get(); } + FPDF_DOCUMENT doc() const { return doc_handle_.get(); } + FPDF_FORMHANDLE form() const { return form_handle_.get(); } + + int form_status() const { return form_status_; } + + void CreateFPDFAvailability(); + void ResetFPDFAvailability(); + + void LoadDocument(const char* password); + + void SetFormStatus(); + void InitializeForm(FPDF_FORMFILLINFO* form_info); + + private: + DocumentLoader* const doc_loader_; + + // Interface structure to provide access to document stream. + std::unique_ptr<FPDF_FILEACCESS> file_access_; + + // Interface structure to check data availability in the document stream. + std::unique_ptr<FX_FILEAVAIL> file_availability_; + + // Interface structure to request data chunks from the document stream. + std::unique_ptr<FX_DOWNLOADHINTS> download_hints_; + + // Pointer to the document availability interface. + ScopedFPDFAvail fpdf_availability_; + + // The PDFium wrapper object for the document. Must come after + // |fpdf_availability_| to prevent outliving it. + ScopedFPDFDocument doc_handle_; + + // The PDFium wrapper for form data. Used even if there are no form controls + // on the page. Must come after |doc_handle_| to prevent outliving it. + ScopedFPDFFormHandle form_handle_; + + // Current form availability status. + int form_status_ = PDF_FORM_NOTAVAIL; + + DISALLOW_COPY_AND_ASSIGN(PDFiumDocument); +}; + +} // namespace chrome_pdf + +#endif // PDF_PDFIUM_PDFIUM_DOCUMENT_H_ diff --git a/chromium/pdf/pdfium/pdfium_engine.cc b/chromium/pdf/pdfium/pdfium_engine.cc index dd69e01314f..d67cb1af557 100644 --- a/chromium/pdf/pdfium/pdfium_engine.cc +++ b/chromium/pdf/pdfium/pdfium_engine.cc @@ -20,6 +20,7 @@ #include "base/logging.h" #include "base/stl_util.h" #include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" @@ -30,8 +31,10 @@ #include "pdf/draw_utils.h" #include "pdf/pdf_transform.h" #include "pdf/pdfium/pdfium_api_string_buffer_adapter.h" +#include "pdf/pdfium/pdfium_document.h" #include "pdf/pdfium/pdfium_mem_buffer_file_read.h" #include "pdf/pdfium/pdfium_mem_buffer_file_write.h" +#include "pdf/pdfium/pdfium_unsupported_features.h" #include "pdf/url_loader_wrapper_impl.h" #include "ppapi/cpp/instance.h" #include "ppapi/cpp/private/pdf.h" @@ -419,19 +422,6 @@ void Release(FPDF_SYSFONTINFO* sysfontinfo) { PDFiumEngine::CreateDocumentLoaderFunction g_create_document_loader_for_testing = nullptr; -PDFiumEngine* g_engine_for_unsupported = nullptr; - -void Unsupported_Handler(UNSUPPORT_INFO*, int type) { - if (!g_engine_for_unsupported) { - NOTREACHED(); - return; - } - - g_engine_for_unsupported->UnsupportedFeature(type); -} - -UNSUPPORT_INFO g_unsupported_info = {1, Unsupported_Handler}; - template <class S> bool IsAboveOrDirectlyLeftOf(const S& lhs, const S& rhs) { return lhs.y() < rhs.y() || (lhs.y() == rhs.y() && lhs.x() < rhs.x()); @@ -669,7 +659,7 @@ bool InitializeSDK() { FPDF_SetSystemFontInfo(g_font_info); #endif - FSDK_SetUnSpObjProcessHandler(&g_unsupported_info); + InitializeUnsupportedFeaturesHandler(); return true; } @@ -689,25 +679,13 @@ std::unique_ptr<PDFEngine> PDFEngine::Create(PDFEngine::Client* client, PDFiumEngine::PDFiumEngine(PDFEngine::Client* client, bool enable_javascript) : client_(client), + form_filler_(this, enable_javascript), mouse_down_state_(PDFiumPage::NONSELECTABLE_AREA, PDFiumPage::LinkTarget()), - form_filler_(this, enable_javascript), print_(this) { find_factory_.Initialize(this); password_factory_.Initialize(this); - file_access_.m_FileLen = 0; - file_access_.m_GetBlock = &GetBlock; - file_access_.m_Param = this; - - file_availability_.version = 1; - file_availability_.IsDataAvail = &IsDataAvail; - file_availability_.engine = this; - - download_hints_.version = 1; - download_hints_.AddSegment = &AddSegment; - download_hints_.engine = this; - IFSDK_PAUSE::version = 1; IFSDK_PAUSE::user = nullptr; IFSDK_PAUSE::NeedToPauseNow = Pause_NeedToPauseNow; @@ -724,7 +702,7 @@ PDFiumEngine::~PDFiumEngine() { for (auto& page : pages_) page->Unload(); - if (doc_) + if (doc()) FORM_DoDocumentAAction(form(), FPDFDOC_AACTION_WC); } @@ -734,28 +712,6 @@ void PDFiumEngine::SetCreateDocumentLoaderFunctionForTesting( g_create_document_loader_for_testing = function; } -int PDFiumEngine::GetBlock(void* param, - unsigned long position, - unsigned char* buffer, - unsigned long size) { - PDFiumEngine* engine = static_cast<PDFiumEngine*>(param); - return engine->doc_loader_->GetBlock(position, size, buffer); -} - -FPDF_BOOL PDFiumEngine::IsDataAvail(FX_FILEAVAIL* param, - size_t offset, - size_t size) { - auto* file_avail = static_cast<FileAvail*>(param); - return file_avail->engine->doc_loader_->IsDataAvailable(offset, size); -} - -void PDFiumEngine::AddSegment(FX_DOWNLOADHINTS* param, - size_t offset, - size_t size) { - auto* download_hints = static_cast<DownloadHints*>(param); - return download_hints->engine->doc_loader_->RequestData(offset, size); -} - bool PDFiumEngine::New(const char* url, const char* headers) { url_ = url; if (headers) @@ -900,6 +856,7 @@ bool PDFiumEngine::HandleDocumentLoad(const pp::URLLoader& loader) { if (!doc_loader_->Init(std::move(loader_wrapper), url_)) return false; } + document_ = std::make_unique<PDFiumDocument>(doc_loader_.get()); // request initial data. doc_loader_->RequestData(0, 1); @@ -929,12 +886,6 @@ void PDFiumEngine::AppendPage(PDFEngine* engine, int index) { client_->Invalidate(GetPageScreenRect(index)); } -#if defined(PDF_ENABLE_XFA) -void PDFiumEngine::SetScrollPosition(const pp::Point& position) { - position_ = position; -} -#endif - std::string PDFiumEngine::GetMetadata(const std::string& key) { return GetDocumentMetadata(doc(), key); } @@ -942,11 +893,11 @@ std::string PDFiumEngine::GetMetadata(const std::string& key) { void PDFiumEngine::OnPendingRequestComplete() { if (!process_when_pending_request_complete_) return; - if (!fpdf_availability_) { - file_access_.m_FileLen = doc_loader_->GetDocumentSize(); - fpdf_availability_.reset( - FPDFAvail_Create(&file_availability_, &file_access_)); - DCHECK(fpdf_availability_); + + if (!fpdf_availability()) { + document_->file_access().m_FileLen = doc_loader_->GetDocumentSize(); + document_->CreateFPDFAvailability(); + DCHECK(fpdf_availability()); // Currently engine does not deal efficiently with some non-linearized // files. // See http://code.google.com/p/chromium/issues/detail?id=59400 @@ -955,12 +906,12 @@ void PDFiumEngine::OnPendingRequestComplete() { if (FPDFAvail_IsLinearized(fpdf_availability()) != PDF_LINEARIZED) { // Wait complete document. process_when_pending_request_complete_ = false; - fpdf_availability_.reset(); + document_->ResetFPDFAvailability(); return; } } - if (!doc_) { + if (!doc()) { LoadDocument(); return; } @@ -995,14 +946,13 @@ void PDFiumEngine::OnNewDataReceived() { } void PDFiumEngine::OnDocumentComplete() { - if (doc_) + if (doc()) return FinishLoadingDocument(); - file_access_.m_FileLen = doc_loader_->GetDocumentSize(); - if (!fpdf_availability_) { - fpdf_availability_.reset( - FPDFAvail_Create(&file_availability_, &file_access_)); - DCHECK(fpdf_availability_); + document_->file_access().m_FileLen = doc_loader_->GetDocumentSize(); + if (!fpdf_availability()) { + document_->CreateFPDFAvailability(); + DCHECK(fpdf_availability()); } LoadDocument(); } @@ -1019,11 +969,12 @@ void PDFiumEngine::CancelBrowserDownload() { } void PDFiumEngine::FinishLoadingDocument() { - DCHECK(doc_); + DCHECK(doc()); DCHECK(doc_loader_->IsDocumentComplete()); LoadBody(); + FX_DOWNLOADHINTS& download_hints = document_->download_hints(); bool need_update = false; for (size_t i = 0; i < pages_.size(); ++i) { if (pages_[i]->available()) @@ -1032,7 +983,7 @@ void PDFiumEngine::FinishLoadingDocument() { pages_[i]->set_available(true); // We still need to call IsPageAvail() even if the whole document is // already downloaded. - FPDFAvail_IsPageAvail(fpdf_availability(), i, &download_hints_); + FPDFAvail_IsPageAvail(fpdf_availability(), i, &download_hints); need_update = true; if (IsPageVisible(i)) client_->Invalidate(GetPageScreenRect(i)); @@ -1052,7 +1003,7 @@ void PDFiumEngine::FinishLoadingDocument() { FORM_DoPageAAction(new_page, form(), FPDFPAGE_AACTION_OPEN); } - if (doc_) { + if (doc()) { DocumentFeatures document_features; document_features.page_count = pages_.size(); document_features.has_attachments = (FPDFDoc_GetAttachmentCount(doc()) > 0); @@ -1066,49 +1017,7 @@ void PDFiumEngine::FinishLoadingDocument() { } } -void PDFiumEngine::UnsupportedFeature(int type) { - std::string feature; - switch (type) { -#if !defined(PDF_ENABLE_XFA) - case FPDF_UNSP_DOC_XFAFORM: - feature = "XFA"; - break; -#endif - case FPDF_UNSP_DOC_PORTABLECOLLECTION: - feature = "Portfolios_Packages"; - break; - case FPDF_UNSP_DOC_ATTACHMENT: - case FPDF_UNSP_ANNOT_ATTACHMENT: - feature = "Attachment"; - break; - case FPDF_UNSP_DOC_SECURITY: - feature = "Rights_Management"; - break; - case FPDF_UNSP_DOC_SHAREDREVIEW: - feature = "Shared_Review"; - break; - case FPDF_UNSP_DOC_SHAREDFORM_ACROBAT: - case FPDF_UNSP_DOC_SHAREDFORM_FILESYSTEM: - case FPDF_UNSP_DOC_SHAREDFORM_EMAIL: - feature = "Shared_Form"; - break; - case FPDF_UNSP_ANNOT_3DANNOT: - feature = "3D"; - break; - case FPDF_UNSP_ANNOT_MOVIE: - feature = "Movie"; - break; - case FPDF_UNSP_ANNOT_SOUND: - feature = "Sound"; - break; - case FPDF_UNSP_ANNOT_SCREEN_MEDIA: - case FPDF_UNSP_ANNOT_SCREEN_RICHMEDIA: - feature = "Screen"; - break; - case FPDF_UNSP_ANNOT_SIG: - feature = "Digital_Signature"; - break; - } +void PDFiumEngine::UnsupportedFeature(const std::string& feature) { client_->DocumentHasUnsupportedFeature(feature); } @@ -1116,6 +1025,18 @@ void PDFiumEngine::FontSubstituted() { client_->FontSubstituted(); } +FPDF_AVAIL PDFiumEngine::fpdf_availability() const { + return document_ ? document_->fpdf_availability() : nullptr; +} + +FPDF_DOCUMENT PDFiumEngine::doc() const { + return document_ ? document_->doc() : nullptr; +} + +FPDF_FORMHANDLE PDFiumEngine::form() const { + return document_ ? document_->form() : nullptr; +} + void PDFiumEngine::ContinueFind(int32_t result) { StartFind(current_find_text_, result != 0); } @@ -1147,7 +1068,7 @@ bool PDFiumEngine::HandleEvent(const pp::InputEvent& event) { rv = OnChar(pp::KeyboardInputEvent(event)); break; case PP_INPUTEVENT_TYPE_TOUCHSTART: { - KillTouchTimer(next_touch_timer_id_); + KillTouchTimer(); pp::TouchInputEvent touch_event(event); if (touch_event.GetTouchCount(PP_TOUCHLIST_TYPE_TARGETTOUCHES) == 1) @@ -1155,12 +1076,12 @@ bool PDFiumEngine::HandleEvent(const pp::InputEvent& event) { break; } case PP_INPUTEVENT_TYPE_TOUCHEND: - KillTouchTimer(next_touch_timer_id_); + KillTouchTimer(); break; case PP_INPUTEVENT_TYPE_TOUCHMOVE: // TODO(dsinclair): This should allow a little bit of movement (up to the // touch radii) to account for finger jiggle. - KillTouchTimer(next_touch_timer_id_); + KillTouchTimer(); break; default: break; @@ -1221,7 +1142,7 @@ pp::Buffer_Dev PDFiumEngine::PrintPagesAsRasterPDF( DCHECK(page_range_count); // If document is not downloaded yet, disable printing. - if (doc_ && !doc_loader_->IsDocumentComplete()) + if (doc() && !doc_loader_->IsDocumentComplete()) return pp::Buffer_Dev(); KillFormFocus(); @@ -1240,7 +1161,7 @@ pp::Buffer_Dev PDFiumEngine::PrintPagesAsPDF( const PP_PrintSettings_Dev& print_settings, const PP_PdfPrintSettings_Dev& pdf_print_settings) { DCHECK(page_range_count); - DCHECK(doc_); + DCHECK(doc()); KillFormFocus(); @@ -1406,7 +1327,7 @@ bool PDFiumEngine::OnLeftMouseDown(const pp::MouseInputEvent& event) { is_form_text_area && IsPointInEditableFormTextArea(page, page_x, page_y, form_type); - FORM_OnLButtonDown(form(), page, 0, page_x, page_y); + FORM_OnLButtonDown(form(), page, event.GetModifiers(), page_x, page_y); if (form_type != FPDF_FORMFIELD_UNKNOWN) { // Destroy SelectionChangeInvalidator object before SetInFormTextArea() // changes plugin's focus to be in form text area. This way, regular text @@ -1556,18 +1477,18 @@ bool PDFiumEngine::OnMouseUp(const pp::MouseInputEvent& event) { // Open link on mouse up for same link for which mouse down happened earlier. if (mouse_down_state_.Matches(area, target)) { - if (area == PDFiumPage::WEBLINK_AREA) { - uint32_t modifiers = event.GetModifiers(); - bool middle_button = - !!(modifiers & PP_INPUTEVENT_MODIFIER_MIDDLEBUTTONDOWN); - bool alt_key = !!(modifiers & PP_INPUTEVENT_MODIFIER_ALTKEY); - bool ctrl_key = !!(modifiers & PP_INPUTEVENT_MODIFIER_CONTROLKEY); - bool meta_key = !!(modifiers & PP_INPUTEVENT_MODIFIER_METAKEY); - bool shift_key = !!(modifiers & PP_INPUTEVENT_MODIFIER_SHIFTKEY); + uint32_t modifiers = event.GetModifiers(); + bool middle_button = + !!(modifiers & PP_INPUTEVENT_MODIFIER_MIDDLEBUTTONDOWN); + bool alt_key = !!(modifiers & PP_INPUTEVENT_MODIFIER_ALTKEY); + bool ctrl_key = !!(modifiers & PP_INPUTEVENT_MODIFIER_CONTROLKEY); + bool meta_key = !!(modifiers & PP_INPUTEVENT_MODIFIER_METAKEY); + bool shift_key = !!(modifiers & PP_INPUTEVENT_MODIFIER_SHIFTKEY); - WindowOpenDisposition disposition = ui::DispositionFromClick( - middle_button, alt_key, ctrl_key, meta_key, shift_key); + WindowOpenDisposition disposition = ui::DispositionFromClick( + middle_button, alt_key, ctrl_key, meta_key, shift_key); + if (area == PDFiumPage::WEBLINK_AREA) { client_->NavigateTo(target.url, disposition); SetInFormTextArea(false); return true; @@ -1576,12 +1497,25 @@ bool PDFiumEngine::OnMouseUp(const pp::MouseInputEvent& event) { if (!PageIndexInBounds(target.page)) return true; - pp::Rect page_rect(GetPageScreenRect(target.page)); - int y = position_.y() + page_rect.y(); - if (target.y_in_pixels) - y += target.y_in_pixels.value() * current_zoom_; - client_->ScrollToY(y, /*compensate_for_toolbar=*/true); + if (disposition == WindowOpenDisposition::CURRENT_TAB) { + pp::Rect page_rect(GetPageScreenRect(target.page)); + int y = position_.y() + page_rect.y(); + if (target.y_in_pixels) + y += target.y_in_pixels.value() * current_zoom_; + + client_->ScrollToY(y, /*compensate_for_toolbar=*/true); + } else { + std::string parameters = + base::StringPrintf("#page=%d", target.page + 1); + if (target.y_in_pixels) { + parameters += base::StringPrintf( + "&zoom=100,0,%d", static_cast<int>(target.y_in_pixels.value())); + } + + client_->NavigateTo(parameters, disposition); + } SetInFormTextArea(false); + return true; } } @@ -1600,7 +1534,8 @@ bool PDFiumEngine::OnMouseUp(const pp::MouseInputEvent& event) { double page_x; double page_y; DeviceToPage(page_index, point, &page_x, &page_y); - FORM_OnLButtonUp(form(), pages_[page_index]->GetPage(), 0, page_x, page_y); + FORM_OnLButtonUp(form(), pages_[page_index]->GetPage(), + event.GetModifiers(), page_x, page_y); } if (!selecting_) @@ -2430,25 +2365,6 @@ void PDFiumEngine::SetGrayscale(bool grayscale) { render_grayscale_ = grayscale; } -void PDFiumEngine::OnCallback(int id) { - auto it = formfill_timers_.find(id); - if (it == formfill_timers_.end()) - return; - - it->second.timer_callback(id); - it = formfill_timers_.find(id); // The callback might delete the timer. - if (it != formfill_timers_.end()) - client_->ScheduleCallback(id, it->second.timer_period); -} - -void PDFiumEngine::OnTouchTimerCallback(int id) { - if (!touch_timers_.count(id)) - return; - - HandleLongPress(touch_timers_[id]); - KillTouchTimer(id); -} - void PDFiumEngine::HandleLongPress(const pp::TouchInputEvent& event) { pp::FloatPoint fp = event.GetTouchByIndex(PP_TOUCHLIST_TYPE_TARGETTOUCHES, 0).position(); @@ -2523,7 +2439,7 @@ bool PDFiumEngine::GetPageSizeAndUniformity(pp::Size* size) { void PDFiumEngine::AppendBlankPages(int num_pages) { DCHECK_NE(num_pages, 0); - if (!doc_) + if (!doc()) return; selection_.clear(); @@ -2579,9 +2495,10 @@ void PDFiumEngine::AppendBlankPages(int num_pages) { void PDFiumEngine::LoadDocument() { // Check if the document is ready for loading. If it isn't just bail for now, // we will call LoadDocument() again later. - if (!doc_ && !doc_loader_->IsDocumentComplete() && - !FPDFAvail_IsDocAvail(fpdf_availability(), &download_hints_)) { - return; + if (!doc() && !doc_loader_->IsDocumentComplete()) { + FX_DOWNLOADHINTS& download_hints = document_->download_hints(); + if (!FPDFAvail_IsDocAvail(fpdf_availability(), &download_hints)) + return; } // If we're in the middle of getting a password, just return. We will retry @@ -2605,11 +2522,12 @@ void PDFiumEngine::LoadDocument() { bool PDFiumEngine::TryLoadingDoc(const std::string& password, bool* needs_password) { *needs_password = false; - if (doc_) { + if (doc()) { // This is probably not necessary, because it should have already been // called below in the |doc_| initialization path. However, the previous // call may have failed, so call it again for good measure. - FPDFAvail_IsDocAvail(fpdf_availability(), &download_hints_); + FX_DOWNLOADHINTS& download_hints = document_->download_hints(); + FPDFAvail_IsDocAvail(fpdf_availability(), &download_hints); return true; } @@ -2618,13 +2536,8 @@ bool PDFiumEngine::TryLoadingDoc(const std::string& password, password_cstr = password.c_str(); password_tries_remaining_--; } - if (doc_loader_->IsDocumentComplete() && - !FPDFAvail_IsLinearized(fpdf_availability())) { - doc_.reset(FPDF_LoadCustomDocument(&file_access_, password_cstr)); - } else { - doc_.reset(FPDFAvail_GetDocument(fpdf_availability(), password_cstr)); - } - if (!doc_) { + document_->LoadDocument(password_cstr); + if (!doc()) { if (FPDF_GetLastError() == FPDF_ERR_PASSWORD) *needs_password = true; return false; @@ -2632,13 +2545,14 @@ bool PDFiumEngine::TryLoadingDoc(const std::string& password, // Always call FPDFAvail_IsDocAvail() so PDFium initializes internal data // structures. - FPDFAvail_IsDocAvail(fpdf_availability(), &download_hints_); + FX_DOWNLOADHINTS& download_hints = document_->download_hints(); + FPDFAvail_IsDocAvail(fpdf_availability(), &download_hints); return true; } void PDFiumEngine::GetPasswordAndLoad() { getting_password_ = true; - DCHECK(!doc_); + DCHECK(!doc()); DCHECK_EQ(static_cast<unsigned long>(FPDF_ERR_PASSWORD), FPDF_GetLastError()); client_->GetDocumentPassword(password_factory_.NewCallbackWithOutput( &PDFiumEngine::OnGetPasswordComplete)); @@ -2666,7 +2580,7 @@ void PDFiumEngine::ContinueLoadingDocument(const std::string& password) { return; } - if (!doc_) { + if (!doc()) { client_->DocumentLoadFailed(); return; } @@ -2710,8 +2624,9 @@ void PDFiumEngine::LoadPageInfo(bool reload) { if (reload) { page_available = pages_[i]->available(); } else if (is_linear) { + FX_DOWNLOADHINTS& download_hints = document_->download_hints(); int linear_page_avail = - FPDFAvail_IsPageAvail(fpdf_availability(), i, &download_hints_); + FPDFAvail_IsPageAvail(fpdf_availability(), i, &download_hints); page_available = linear_page_avail == PDF_DATA_AVAIL; } else { page_available = doc_complete; @@ -2751,8 +2666,8 @@ void PDFiumEngine::LoadPageInfo(bool reload) { } void PDFiumEngine::LoadBody() { - DCHECK(doc_); - DCHECK(fpdf_availability_); + DCHECK(doc()); + DCHECK(fpdf_availability()); if (doc_loader_->IsDocumentComplete()) { LoadForm(); } else if (FPDFAvail_IsLinearized(fpdf_availability()) == PDF_LINEARIZED && @@ -2761,7 +2676,7 @@ void PDFiumEngine::LoadBody() { // XFA document. And after loading form the page count and its contents may // be changed. LoadForm(); - if (form_status_ == PDF_FORM_NOTAVAIL) + if (document_->form_status() == PDF_FORM_NOTAVAIL) return; } LoadPages(); @@ -2780,12 +2695,14 @@ void PDFiumEngine::LoadPages() { } void PDFiumEngine::LoadForm() { - if (form_) + if (form()) return; - DCHECK(doc_); - form_status_ = FPDFAvail_IsFormAvail(fpdf_availability(), &download_hints_); - if (form_status_ != PDF_FORM_NOTAVAIL || doc_loader_->IsDocumentComplete()) { - form_.reset(FPDFDOC_InitFormFillEnvironment(doc(), &form_filler_)); + + DCHECK(doc()); + document_->SetFormStatus(); + if (document_->form_status() != PDF_FORM_NOTAVAIL || + doc_loader_->IsDocumentComplete()) { + document_->InitializeForm(&form_filler_); #if defined(PDF_ENABLE_XFA) FPDF_LoadXFA(doc()); #endif @@ -2794,7 +2711,7 @@ void PDFiumEngine::LoadForm() { kFormHighlightColor); FPDF_SetFormFieldHighlightAlpha(form(), kFormHighlightAlpha); } -} // namespace chrome_pdf +} void PDFiumEngine::CalculateVisiblePages() { if (!doc_loader_) @@ -2870,14 +2787,15 @@ void PDFiumEngine::ScrollToPage(int page) { } bool PDFiumEngine::CheckPageAvailable(int index, std::vector<int>* pending) { - if (!doc_) + if (!doc()) return false; const int num_pages = static_cast<int>(pages_.size()); if (index < num_pages && pages_[index]->available()) return true; - if (!FPDFAvail_IsPageAvail(fpdf_availability(), index, &download_hints_)) { + FX_DOWNLOADHINTS& download_hints = document_->download_hints(); + if (!FPDFAvail_IsPageAvail(fpdf_availability(), index, &download_hints)) { if (!base::ContainsValue(*pending, index)) pending->push_back(index); return false; @@ -3394,7 +3312,7 @@ int PDFiumEngine::GetVisiblePageIndex(FPDF_PAGE page) { void PDFiumEngine::SetCurrentPage(int index) { in_flight_visible_page_.reset(); - if (index == most_visible_page_ || !form_) + if (index == most_visible_page_ || !form()) return; if (most_visible_page_ != -1 && called_do_document_action_) { @@ -3578,13 +3496,13 @@ bool PDFiumEngine::IsPointInEditableFormTextArea(FPDF_PAGE page, } void PDFiumEngine::ScheduleTouchTimer(const pp::TouchInputEvent& evt) { - touch_timers_[++next_touch_timer_id_] = evt; - client_->ScheduleTouchTimerCallback(next_touch_timer_id_, - kTouchLongPressTimeout); + touch_timer_.Start(FROM_HERE, kTouchLongPressTimeout, + base::BindRepeating(&PDFiumEngine::HandleLongPress, + base::Unretained(this), evt)); } -void PDFiumEngine::KillTouchTimer(int timer_id) { - touch_timers_.erase(timer_id); +void PDFiumEngine::KillTouchTimer() { + touch_timer_.Stop(); } bool PDFiumEngine::PageIndexInBounds(int index) const { @@ -3670,10 +3588,6 @@ void PDFiumEngine::GetSelection(uint32_t* selection_start_page_index, } } -PDFiumEngine::FormFillTimerData::FormFillTimerData(base::TimeDelta period, - TimerCallback callback) - : timer_period(period), timer_callback(callback) {} - PDFiumEngine::ProgressivePaint::ProgressivePaint(int index, const pp::Rect& rect) : page_index_(index), rect_(rect) {} @@ -3693,15 +3607,6 @@ void PDFiumEngine::ProgressivePaint::SetBitmapAndImageData( image_data_ = std::move(image_data); } -ScopedUnsupportedFeature::ScopedUnsupportedFeature(PDFiumEngine* engine) - : old_engine_(g_engine_for_unsupported) { - g_engine_for_unsupported = engine; -} - -ScopedUnsupportedFeature::~ScopedUnsupportedFeature() { - g_engine_for_unsupported = old_engine_; -} - ScopedSubstFont::ScopedSubstFont(PDFiumEngine* engine) : old_engine_(g_engine_for_fontmapper) { g_engine_for_fontmapper = engine; diff --git a/chromium/pdf/pdfium/pdfium_engine.h b/chromium/pdf/pdfium/pdfium_engine.h index 817ea40f9c5..5e0c878be58 100644 --- a/chromium/pdf/pdfium/pdfium_engine.h +++ b/chromium/pdf/pdfium/pdfium_engine.h @@ -16,6 +16,7 @@ #include "base/macros.h" #include "base/optional.h" #include "base/time/time.h" +#include "base/timer/timer.h" #include "pdf/document_loader.h" #include "pdf/pdf_engine.h" #include "pdf/pdfium/pdfium_form_filler.h" @@ -30,13 +31,13 @@ #include "ppapi/cpp/var_array.h" #include "ppapi/utility/completion_callback_factory.h" #include "third_party/pdfium/public/cpp/fpdf_scopers.h" -#include "third_party/pdfium/public/fpdf_dataavail.h" #include "third_party/pdfium/public/fpdf_formfill.h" #include "third_party/pdfium/public/fpdf_progressive.h" #include "third_party/pdfium/public/fpdfview.h" namespace chrome_pdf { +class PDFiumDocument; class ShadowMatrix; class PDFiumEngine : public PDFEngine, @@ -103,8 +104,6 @@ class PDFiumEngine : public PDFEngine, pp::Rect GetPageScreenRect(int page_index) const override; int GetVerticalScrollbarYPosition() override; void SetGrayscale(bool grayscale) override; - void OnCallback(int id) override; - void OnTouchTimerCallback(int id) override; int GetCharCount(int page_index) override; pp::FloatRect GetCharBounds(int page_index, int char_index) override; uint32_t GetCharUnicode(int page_index, int char_index) override; @@ -119,9 +118,6 @@ class PDFiumEngine : public PDFEngine, bool GetPageSizeAndUniformity(pp::Size* size) override; void AppendBlankPages(int num_pages) override; void AppendPage(PDFEngine* engine, int index) override; -#if defined(PDF_ENABLE_XFA) - void SetScrollPosition(const pp::Point& position) override; -#endif std::string GetMetadata(const std::string& key) override; void SetCaretPosition(const pp::Point& position) override; void MoveRangeSelectionExtent(const pp::Point& extent) override; @@ -142,12 +138,12 @@ class PDFiumEngine : public PDFEngine, void CancelBrowserDownload() override; void KillFormFocus() override; - void UnsupportedFeature(int type); + void UnsupportedFeature(const std::string& feature); void FontSubstituted(); - FPDF_AVAIL fpdf_availability() const { return fpdf_availability_.get(); } - FPDF_DOCUMENT doc() const { return doc_.get(); } - FPDF_FORMHANDLE form() const { return form_.get(); } + FPDF_AVAIL fpdf_availability() const; + FPDF_DOCUMENT doc() const; + FPDF_FORMHANDLE form() const; private: // This helper class is used to detect the difference in selection between @@ -198,26 +194,6 @@ class PDFiumEngine : public PDFEngine, friend class PDFiumFormFiller; friend class SelectionChangeInvalidator; - struct FileAvail : public FX_FILEAVAIL { - PDFiumEngine* engine; - }; - - struct DownloadHints : public FX_DOWNLOADHINTS { - PDFiumEngine* engine; - }; - - // PDFium interface to get block of data. - static int GetBlock(void* param, - unsigned long position, - unsigned char* buffer, - unsigned long size); - - // PDFium interface to check is block of data is available. - static FPDF_BOOL IsDataAvail(FX_FILEAVAIL* param, size_t offset, size_t size); - - // PDFium interface to request download of the block of data. - static void AddSegment(FX_DOWNLOADHINTS* param, size_t offset, size_t size); - // We finished getting the pdf file, so load it. This will complete // asynchronously (due to password fetching) and may be run multiple times. void LoadDocument(); @@ -476,7 +452,7 @@ class PDFiumEngine : public PDFEngine, float GetToolbarHeightInScreenCoords(); void ScheduleTouchTimer(const pp::TouchInputEvent& event); - void KillTouchTimer(int timer_id); + void KillTouchTimer(); void HandleLongPress(const pp::TouchInputEvent& event); // Returns a VarDictionary (representing a bookmark), which in turn contains @@ -515,41 +491,11 @@ class PDFiumEngine : public PDFEngine, bool getting_password_ = false; int password_tries_remaining_ = 0; - // Used to manage timers that form fill API needs. The key is the timer id. - // The value holds the timer period and the callback function. - struct FormFillTimerData { - FormFillTimerData(base::TimeDelta period, TimerCallback callback); - - base::TimeDelta timer_period; - TimerCallback timer_callback; - }; - - // Needs to be above pages_, as destroying a page may stop timers. - std::map<int, const FormFillTimerData> formfill_timers_; - int next_formfill_timer_id_ = 0; - - // Interface structure to provide access to document stream. - FPDF_FILEACCESS file_access_; - - // Interface structure to check data availability in the document stream. - FileAvail file_availability_; - - // Interface structure to request data chunks from the document stream. - DownloadHints download_hints_; - - // Pointer to the document availability interface. - ScopedFPDFAvail fpdf_availability_; - - // The PDFium wrapper object for the document. Must come after - // |fpdf_availability_| to prevent outliving it. - ScopedFPDFDocument doc_; - - // The PDFium wrapper for form data. Used even if there are no form controls - // on the page. Must come after |doc_| to prevent outliving it. - ScopedFPDFFormHandle form_; + // Needs to be above pages_, as destroying a page may call some methods of + // form filler. + PDFiumFormFiller form_filler_; - // Current form availability status. - int form_status_ = PDF_FORM_NOTAVAIL; + std::unique_ptr<PDFiumDocument> document_; // The page(s) of the document. std::vector<std::unique_ptr<PDFiumPage>> pages_; @@ -618,9 +564,8 @@ class PDFiumEngine : public PDFEngine, pp::Size default_page_size_; - // Used to manage timers for touch long press. - std::map<int, pp::TouchInputEvent> touch_timers_; - int next_touch_timer_id_ = 0; + // Timer for touch long press detection. + base::OneShotTimer touch_timer_; // Holds the zero-based page index of the last page that the mouse clicked on. int last_page_mouse_down_ = -1; @@ -704,26 +649,12 @@ class PDFiumEngine : public PDFEngine, bool edit_mode_ = false; - PDFiumFormFiller form_filler_; PDFiumPrint print_; DISALLOW_COPY_AND_ASSIGN(PDFiumEngine); }; // Create a local variable of this when calling PDFium functions which can call -// our global callback when an unsupported feature is reached. -class ScopedUnsupportedFeature { - public: - explicit ScopedUnsupportedFeature(PDFiumEngine* engine); - ~ScopedUnsupportedFeature(); - - private: - PDFiumEngine* const old_engine_; - - DISALLOW_COPY_AND_ASSIGN(ScopedUnsupportedFeature); -}; - -// Create a local variable of this when calling PDFium functions which can call // our global callback when a substitute font is mapped. class ScopedSubstFont { public: diff --git a/chromium/pdf/pdfium/pdfium_engine_exports_unittest.cc b/chromium/pdf/pdfium/pdfium_engine_exports_unittest.cc new file mode 100644 index 00000000000..fe83add7857 --- /dev/null +++ b/chromium/pdf/pdfium/pdfium_engine_exports_unittest.cc @@ -0,0 +1,101 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/files/file_util.h" +#include "base/path_service.h" +#include "base/test/test_simple_task_runner.h" +#include "base/threading/thread_task_runner_handle.h" +#include "gin/v8_initializer.h" +#include "pdf/pdf.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace chrome_pdf { + +namespace { + +void LoadV8SnapshotData() { +#if defined(V8_USE_EXTERNAL_STARTUP_DATA) + static bool loaded = false; + if (!loaded) { + loaded = true; + gin::V8Initializer::LoadV8Snapshot(); + gin::V8Initializer::LoadV8Natives(); + } +#endif +} + +class PDFiumEngineExportsTest : public testing::Test { + public: + PDFiumEngineExportsTest() = default; + ~PDFiumEngineExportsTest() override = default; + + protected: + void SetUp() override { + LoadV8SnapshotData(); + + handle_ = std::make_unique<base::ThreadTaskRunnerHandle>( + base::MakeRefCounted<base::TestSimpleTaskRunner>()); + + CHECK(base::PathService::Get(base::DIR_SOURCE_ROOT, &pdf_data_dir_)); + pdf_data_dir_ = pdf_data_dir_.Append(FILE_PATH_LITERAL("pdf")) + .Append(FILE_PATH_LITERAL("test")) + .Append(FILE_PATH_LITERAL("data")); + } + + const base::FilePath& pdf_data_dir() const { return pdf_data_dir_; } + + private: + std::unique_ptr<base::ThreadTaskRunnerHandle> handle_; + base::FilePath pdf_data_dir_; + + DISALLOW_COPY_AND_ASSIGN(PDFiumEngineExportsTest); +}; + +} // namespace + +TEST_F(PDFiumEngineExportsTest, GetPDFDocInfo) { + base::FilePath pdf_path = + pdf_data_dir().Append(FILE_PATH_LITERAL("hello_world2.pdf")); + std::string pdf_data; + ASSERT_TRUE(base::ReadFileToString(pdf_path, &pdf_data)); + + EXPECT_FALSE(GetPDFDocInfo(nullptr, 0, nullptr, nullptr)); + + ASSERT_TRUE( + GetPDFDocInfo(pdf_data.data(), pdf_data.size(), nullptr, nullptr)); + + int page_count; + double max_page_width; + ASSERT_TRUE(GetPDFDocInfo(pdf_data.data(), pdf_data.size(), &page_count, + &max_page_width)); + EXPECT_EQ(2, page_count); + EXPECT_DOUBLE_EQ(200.0, max_page_width); +} + +TEST_F(PDFiumEngineExportsTest, GetPDFPageSizeByIndex) { + // TODO(thestig): Use a better PDF for this test, as hello_world2.pdf's page + // dimensions are uninteresting. + base::FilePath pdf_path = + pdf_data_dir().Append(FILE_PATH_LITERAL("hello_world2.pdf")); + std::string pdf_data; + ASSERT_TRUE(base::ReadFileToString(pdf_path, &pdf_data)); + + EXPECT_FALSE(GetPDFPageSizeByIndex(nullptr, 0, 0, nullptr, nullptr)); + + int page_count; + ASSERT_TRUE( + GetPDFDocInfo(pdf_data.data(), pdf_data.size(), &page_count, nullptr)); + ASSERT_EQ(2, page_count); + for (int page_number = 0; page_number < page_count; ++page_number) { + double width; + double height; + ASSERT_TRUE(GetPDFPageSizeByIndex(pdf_data.data(), pdf_data.size(), + page_number, &width, &height)); + EXPECT_DOUBLE_EQ(200.0, width); + EXPECT_DOUBLE_EQ(200.0, height); + } +} + +} // namespace chrome_pdf diff --git a/chromium/pdf/pdfium/pdfium_form_filler.cc b/chromium/pdf/pdfium/pdfium_form_filler.cc index 0e273b9a7e2..c64ccafcf45 100644 --- a/chromium/pdf/pdfium/pdfium_form_filler.cc +++ b/chromium/pdf/pdfium/pdfium_form_filler.cc @@ -6,6 +6,7 @@ #include <algorithm> #include <string> +#include <utility> #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" @@ -79,6 +80,8 @@ PDFiumFormFiller::PDFiumFormFiller(PDFiumEngine* engine, bool enable_javascript) } } +PDFiumFormFiller::~PDFiumFormFiller() = default; + // static void PDFiumFormFiller::Form_Invalidate(FPDF_FORMFILLINFO* param, FPDF_PAGE page, @@ -133,21 +136,15 @@ void PDFiumFormFiller::Form_SetCursor(FPDF_FORMFILLINFO* param, int PDFiumFormFiller::Form_SetTimer(FPDF_FORMFILLINFO* param, int elapse, TimerCallback timer_func) { - PDFiumEngine* engine = GetEngine(param); - base::TimeDelta elapse_time = base::TimeDelta::FromMilliseconds(elapse); - engine->formfill_timers_.emplace( - std::piecewise_construct, - std::forward_as_tuple(++engine->next_formfill_timer_id_), - std::forward_as_tuple(elapse_time, timer_func)); - engine->client_->ScheduleCallback(engine->next_formfill_timer_id_, - elapse_time); - return engine->next_formfill_timer_id_; + auto* form_filler = static_cast<PDFiumFormFiller*>(param); + return form_filler->SetTimer(base::TimeDelta::FromMilliseconds(elapse), + timer_func); } // static void PDFiumFormFiller::Form_KillTimer(FPDF_FORMFILLINFO* param, int timer_id) { - PDFiumEngine* engine = GetEngine(param); - engine->formfill_timers_.erase(timer_id); + auto* form_filler = static_cast<PDFiumFormFiller*>(param); + form_filler->KillTimer(timer_id); } // static @@ -304,10 +301,7 @@ void PDFiumFormFiller::Form_SetCurrentPage(FPDF_FORMFILLINFO* param, FPDF_DOCUMENT document, int page) { PDFiumEngine* engine = GetEngine(param); - pp::Rect page_view_rect = engine->GetPageContentsRect(page); - engine->ScrolledToYPosition(page_view_rect.height()); - pp::Point pos(1, page_view_rect.height()); - engine->SetScrollPosition(pos); + engine->ScrollToPage(page); } // static @@ -629,4 +623,17 @@ PDFiumEngine* PDFiumFormFiller::GetEngine(IPDF_JSPLATFORM* platform) { return form_filler->engine_; } +int PDFiumFormFiller::SetTimer(const base::TimeDelta& delay, + TimerCallback timer_func) { + const int timer_id = ++last_timer_id_; + auto timer = std::make_unique<base::RepeatingTimer>(); + timer->Start(FROM_HERE, delay, base::BindRepeating(timer_func, timer_id)); + timers_[timer_id] = std::move(timer); + return timer_id; +} + +void PDFiumFormFiller::KillTimer(int timer_id) { + timers_.erase(timer_id); +} + } // namespace chrome_pdf diff --git a/chromium/pdf/pdfium/pdfium_form_filler.h b/chromium/pdf/pdfium/pdfium_form_filler.h index ed73fee8e6a..df4c7fb3d47 100644 --- a/chromium/pdf/pdfium/pdfium_form_filler.h +++ b/chromium/pdf/pdfium/pdfium_form_filler.h @@ -5,7 +5,12 @@ #ifndef PDF_PDFIUM_PDFIUM_FORM_FILLER_H_ #define PDF_PDFIUM_PDFIUM_FORM_FILLER_H_ +#include <map> +#include <memory> + #include "base/macros.h" +#include "base/time/time.h" +#include "base/timer/timer.h" #include "third_party/pdfium/public/fpdf_formfill.h" namespace chrome_pdf { @@ -15,6 +20,7 @@ class PDFiumEngine; class PDFiumFormFiller : public FPDF_FORMFILLINFO, public IPDF_JSPLATFORM { public: PDFiumFormFiller(PDFiumEngine* engine, bool enable_javascript); + ~PDFiumFormFiller(); private: // FPDF_FORMFILLINFO callbacks. @@ -165,8 +171,14 @@ class PDFiumFormFiller : public FPDF_FORMFILLINFO, public IPDF_JSPLATFORM { static PDFiumEngine* GetEngine(FPDF_FORMFILLINFO* info); static PDFiumEngine* GetEngine(IPDF_JSPLATFORM* platform); + int SetTimer(const base::TimeDelta& delay, TimerCallback timer_func); + void KillTimer(int timer_id); + PDFiumEngine* const engine_; + std::map<int, std::unique_ptr<base::RepeatingTimer>> timers_; + int last_timer_id_ = 0; + DISALLOW_COPY_AND_ASSIGN(PDFiumFormFiller); }; diff --git a/chromium/pdf/pdfium/pdfium_page.cc b/chromium/pdf/pdfium/pdfium_page.cc index 16e23d75426..37b4db3dfe7 100644 --- a/chromium/pdf/pdfium/pdfium_page.cc +++ b/chromium/pdf/pdfium/pdfium_page.cc @@ -18,6 +18,7 @@ #include "base/strings/utf_string_conversions.h" #include "pdf/pdfium/pdfium_api_string_buffer_adapter.h" #include "pdf/pdfium/pdfium_engine.h" +#include "pdf/pdfium/pdfium_unsupported_features.h" #include "printing/units.h" #include "third_party/pdfium/public/cpp/fpdf_scopers.h" #include "third_party/pdfium/public/fpdf_annot.h" @@ -60,7 +61,10 @@ pp::FloatRect FloatPageRectToPixelRect(FPDF_PAGE page, pp::FloatRect GetFloatCharRectInPixels(FPDF_PAGE page, FPDF_TEXTPAGE text_page, int index) { - double left, right, bottom, top; + double left; + double right; + double bottom; + double top; FPDFText_GetCharBox(text_page, index, &left, &right, &bottom, &top); if (right < left) std::swap(left, right); @@ -97,12 +101,12 @@ PDFiumPage::PDFiumPage(PDFiumEngine* engine, PDFiumPage::PDFiumPage(PDFiumPage&& that) = default; PDFiumPage::~PDFiumPage() { - DCHECK_EQ(0, loading_count_); + DCHECK_EQ(0, preventing_unload_count_); } void PDFiumPage::Unload() { // Do not unload while in the middle of a load. - if (loading_count_) + if (preventing_unload_count_) return; text_page_.reset(); @@ -121,7 +125,7 @@ FPDF_PAGE PDFiumPage::GetPage() { if (!available_) return nullptr; if (!page_) { - ScopedLoadCounter scoped_load(this); + ScopedUnloadPreventer scoped_unload_preventer(this); page_.reset(FPDF_LoadPage(engine_->doc(), index_)); if (page_ && engine_->form()) { FORM_OnAfterLoadPage(page(), engine_->form()); @@ -136,7 +140,7 @@ FPDF_PAGE PDFiumPage::GetPrintPage() { if (!available_) return nullptr; if (!page_) { - ScopedLoadCounter scoped_load(this); + ScopedUnloadPreventer scoped_unload_preventer(this); page_.reset(FPDF_LoadPage(engine_->doc(), index_)); } return page(); @@ -144,7 +148,7 @@ FPDF_PAGE PDFiumPage::GetPrintPage() { void PDFiumPage::ClosePrintPage() { // Do not close |page_| while in the middle of a load. - if (loading_count_) + if (preventing_unload_count_) return; page_.reset(); @@ -154,7 +158,7 @@ FPDF_TEXTPAGE PDFiumPage::GetTextPage() { if (!available_) return nullptr; if (!text_page_) { - ScopedLoadCounter scoped_load(this); + ScopedUnloadPreventer scoped_unload_preventer(this); text_page_.reset(FPDFText_LoadPage(GetPage())); } return text_page(); @@ -420,7 +424,10 @@ int PDFiumPage::GetLink(int char_index, LinkTarget* target) { // Get the bounding box of the rect again, since it might have moved because // of the tolerance above. - double left, right, bottom, top; + double left; + double right; + double bottom; + double top; FPDFText_GetCharBox(GetTextPage(), char_index, &left, &right, &bottom, &top); pp::Point origin( @@ -600,13 +607,13 @@ const PDFEngine::PageFeatures* PDFiumPage::GetPageFeatures() { return &page_features_; } -PDFiumPage::ScopedLoadCounter::ScopedLoadCounter(PDFiumPage* page) +PDFiumPage::ScopedUnloadPreventer::ScopedUnloadPreventer(PDFiumPage* page) : page_(page) { - page_->loading_count_++; + page_->preventing_unload_count_++; } -PDFiumPage::ScopedLoadCounter::~ScopedLoadCounter() { - page_->loading_count_--; +PDFiumPage::ScopedUnloadPreventer::~ScopedUnloadPreventer() { + page_->preventing_unload_count_--; } PDFiumPage::Link::Link() = default; diff --git a/chromium/pdf/pdfium/pdfium_page.h b/chromium/pdf/pdfium/pdfium_page.h index 0d8a137c560..86daadc0ed5 100644 --- a/chromium/pdf/pdfium/pdfium_page.h +++ b/chromium/pdf/pdfium/pdfium_page.h @@ -146,10 +146,10 @@ class PDFiumPage { // NONSELECTABLE_AREA if detection failed. Area GetURITarget(FPDF_ACTION uri_action, LinkTarget* target) const; - class ScopedLoadCounter { + class ScopedUnloadPreventer { public: - explicit ScopedLoadCounter(PDFiumPage* page); - ~ScopedLoadCounter(); + explicit ScopedUnloadPreventer(PDFiumPage* page); + ~ScopedUnloadPreventer(); private: PDFiumPage* const page_; @@ -169,7 +169,7 @@ class PDFiumPage { ScopedFPDFPage page_; ScopedFPDFTextPage text_page_; int index_; - int loading_count_ = 0; + int preventing_unload_count_ = 0; pp::Rect rect_; bool calculated_links_ = false; std::vector<Link> links_; diff --git a/chromium/pdf/pdfium/pdfium_print.cc b/chromium/pdf/pdfium/pdfium_print.cc index 09848a7e97c..ea3e2f372f2 100644 --- a/chromium/pdf/pdfium/pdfium_print.cc +++ b/chromium/pdf/pdfium/pdfium_print.cc @@ -32,9 +32,9 @@ namespace chrome_pdf { namespace { // UI should have done parameter sanity check, when execution -// reaches here, |num_pages_per_sheet| should be a positive integer. -bool ShouldDoNup(int num_pages_per_sheet) { - return num_pages_per_sheet > 1; +// reaches here, |pages_per_sheet| should be a positive integer. +bool ShouldDoNup(int pages_per_sheet) { + return pages_per_sheet > 1; } // Check the source doc orientation. Returns true if the doc is landscape. @@ -294,11 +294,10 @@ pp::Buffer_Dev PDFiumPrint::PrintPagesAsRasterPDF( pp::Buffer_Dev buffer; if (i == pages_to_print.size()) { FPDF_CopyViewerPreferences(output_doc.get(), engine_->doc()); - uint32_t num_pages_per_sheet = pdf_print_settings.num_pages_per_sheet; + uint32_t pages_per_sheet = pdf_print_settings.pages_per_sheet; uint32_t scale_factor = pdf_print_settings.scale_factor; - if (ShouldDoNup(num_pages_per_sheet)) { - buffer = - NupPdfToPdf(output_doc.get(), num_pages_per_sheet, print_settings); + if (ShouldDoNup(pages_per_sheet)) { + buffer = NupPdfToPdf(output_doc.get(), pages_per_sheet, print_settings); } else { FitContentsToPrintableAreaIfRequired( output_doc.get(), scale_factor / 100.0f, print_settings); @@ -330,10 +329,10 @@ pp::Buffer_Dev PDFiumPrint::PrintPagesAsPDF( return pp::Buffer_Dev(); pp::Buffer_Dev buffer; - uint32_t num_pages_per_sheet = pdf_print_settings.num_pages_per_sheet; + uint32_t pages_per_sheet = pdf_print_settings.pages_per_sheet; uint32_t scale_factor = pdf_print_settings.scale_factor; - if (ShouldDoNup(num_pages_per_sheet)) { - buffer = NupPdfToPdf(output_doc.get(), num_pages_per_sheet, print_settings); + if (ShouldDoNup(pages_per_sheet)) { + buffer = NupPdfToPdf(output_doc.get(), pages_per_sheet, print_settings); } else { FitContentsToPrintableAreaIfRequired(output_doc.get(), scale_factor / 100.0f, print_settings); @@ -429,16 +428,16 @@ FPDF_DOCUMENT PDFiumPrint::CreateSinglePageRasterPdf( pp::Buffer_Dev PDFiumPrint::NupPdfToPdf( FPDF_DOCUMENT doc, - uint32_t num_pages_per_sheet, + uint32_t pages_per_sheet, const PP_PrintSettings_Dev& print_settings) { DCHECK(doc); - DCHECK(ShouldDoNup(num_pages_per_sheet)); + DCHECK(ShouldDoNup(pages_per_sheet)); PP_Size page_size = print_settings.paper_size; printing::NupParameters nup_params; bool is_landscape = IsSourcePdfLandscape(doc); - nup_params.SetParameters(num_pages_per_sheet, is_landscape); + nup_params.SetParameters(pages_per_sheet, is_landscape); // Import n pages to one. bool paper_is_landscape = page_size.width > page_size.height; diff --git a/chromium/pdf/pdfium/pdfium_print.h b/chromium/pdf/pdfium/pdfium_print.h index b165d028577..c0df7d99e44 100644 --- a/chromium/pdf/pdfium/pdfium_print.h +++ b/chromium/pdf/pdfium/pdfium_print.h @@ -47,12 +47,12 @@ class PDFiumPrint { const PP_PrintSettings_Dev& print_settings, PDFiumPage* page_to_print); - // Perform N-up PDF generation from |doc| based on |num_pages_per_sheet| and + // Perform N-up PDF generation from |doc| based on |pages_per_sheet| and // the parameters in |print_settings|. // On success, the returned buffer contains the N-up version of |doc|. // On failure, the returned buffer is empty. pp::Buffer_Dev NupPdfToPdf(FPDF_DOCUMENT doc, - uint32_t num_pages_per_sheet, + uint32_t pages_per_sheet, const PP_PrintSettings_Dev& print_settings); bool FlattenPrintData(FPDF_DOCUMENT doc); diff --git a/chromium/pdf/pdfium/pdfium_unsupported_features.cc b/chromium/pdf/pdfium/pdfium_unsupported_features.cc new file mode 100644 index 00000000000..55dbd2d140a --- /dev/null +++ b/chromium/pdf/pdfium/pdfium_unsupported_features.cc @@ -0,0 +1,84 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "pdf/pdfium/pdfium_unsupported_features.h" + +#include "base/logging.h" +#include "pdf/pdfium/pdfium_engine.h" +#include "third_party/pdfium/public/fpdf_ext.h" + +namespace chrome_pdf { + +namespace { + +PDFiumEngine* g_engine_for_unsupported = nullptr; + +void Unsupported_Handler(UNSUPPORT_INFO*, int type) { + if (!g_engine_for_unsupported) { + NOTREACHED(); + return; + } + + std::string feature; + switch (type) { + case FPDF_UNSP_DOC_XFAFORM: + feature = "XFA"; + break; + case FPDF_UNSP_DOC_PORTABLECOLLECTION: + feature = "Portfolios_Packages"; + break; + case FPDF_UNSP_DOC_ATTACHMENT: + case FPDF_UNSP_ANNOT_ATTACHMENT: + feature = "Attachment"; + break; + case FPDF_UNSP_DOC_SECURITY: + feature = "Rights_Management"; + break; + case FPDF_UNSP_DOC_SHAREDREVIEW: + feature = "Shared_Review"; + break; + case FPDF_UNSP_DOC_SHAREDFORM_ACROBAT: + case FPDF_UNSP_DOC_SHAREDFORM_FILESYSTEM: + case FPDF_UNSP_DOC_SHAREDFORM_EMAIL: + feature = "Shared_Form"; + break; + case FPDF_UNSP_ANNOT_3DANNOT: + feature = "3D"; + break; + case FPDF_UNSP_ANNOT_MOVIE: + feature = "Movie"; + break; + case FPDF_UNSP_ANNOT_SOUND: + feature = "Sound"; + break; + case FPDF_UNSP_ANNOT_SCREEN_MEDIA: + case FPDF_UNSP_ANNOT_SCREEN_RICHMEDIA: + feature = "Screen"; + break; + case FPDF_UNSP_ANNOT_SIG: + feature = "Digital_Signature"; + break; + } + + g_engine_for_unsupported->UnsupportedFeature(feature); +} + +UNSUPPORT_INFO g_unsupported_info = {1, Unsupported_Handler}; + +} // namespace + +void InitializeUnsupportedFeaturesHandler() { + FSDK_SetUnSpObjProcessHandler(&g_unsupported_info); +} + +ScopedUnsupportedFeature::ScopedUnsupportedFeature(PDFiumEngine* engine) + : old_engine_(g_engine_for_unsupported) { + g_engine_for_unsupported = engine; +} + +ScopedUnsupportedFeature::~ScopedUnsupportedFeature() { + g_engine_for_unsupported = old_engine_; +} + +} // namespace chrome_pdf diff --git a/chromium/pdf/pdfium/pdfium_unsupported_features.h b/chromium/pdf/pdfium/pdfium_unsupported_features.h new file mode 100644 index 00000000000..35f5e1d20d4 --- /dev/null +++ b/chromium/pdf/pdfium/pdfium_unsupported_features.h @@ -0,0 +1,31 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PDF_PDFIUM_PDFIUM_UNSUPPORTED_FEATURES_H_ +#define PDF_PDFIUM_PDFIUM_UNSUPPORTED_FEATURES_H_ + +#include "base/macros.h" + +namespace chrome_pdf { + +class PDFiumEngine; + +void InitializeUnsupportedFeaturesHandler(); + +// Create a local variable of this when calling PDFium functions which can call +// our global callback when an unsupported feature is reached. +class ScopedUnsupportedFeature { + public: + explicit ScopedUnsupportedFeature(PDFiumEngine* engine); + ~ScopedUnsupportedFeature(); + + private: + PDFiumEngine* const old_engine_; + + DISALLOW_COPY_AND_ASSIGN(ScopedUnsupportedFeature); +}; + +} // namespace chrome_pdf + +#endif // PDF_PDFIUM_PDFIUM_UNSUPPORTED_FEATURES_H_ diff --git a/chromium/pdf/preview_mode_client.cc b/chromium/pdf/preview_mode_client.cc index 02538061a0d..0cad061b0c1 100644 --- a/chromium/pdf/preview_mode_client.cc +++ b/chromium/pdf/preview_mode_client.cc @@ -109,15 +109,6 @@ pp::URLLoader PreviewModeClient::CreateURLLoader() { return pp::URLLoader(); } -void PreviewModeClient::ScheduleCallback(int id, base::TimeDelta delay) { - NOTREACHED(); -} - -void PreviewModeClient::ScheduleTouchTimerCallback(int id, - base::TimeDelta delay) { - NOTREACHED(); -} - std::vector<PDFEngine::Client::SearchStringResult> PreviewModeClient::SearchString(const base::char16* string, const base::char16* term, diff --git a/chromium/pdf/preview_mode_client.h b/chromium/pdf/preview_mode_client.h index 6f5c141158e..c1fb1926cb0 100644 --- a/chromium/pdf/preview_mode_client.h +++ b/chromium/pdf/preview_mode_client.h @@ -56,8 +56,6 @@ class PreviewModeClient : public PDFEngine::Client { const void* data, int length) override; pp::URLLoader CreateURLLoader() override; - void ScheduleCallback(int id, base::TimeDelta delay) override; - void ScheduleTouchTimerCallback(int id, base::TimeDelta delay) override; std::vector<SearchStringResult> SearchString(const base::char16* string, const base::char16* term, bool case_sensitive) override; diff --git a/chromium/pdf/timer.cc b/chromium/pdf/timer.cc deleted file mode 100644 index cbd11a0a38b..00000000000 --- a/chromium/pdf/timer.cc +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "pdf/timer.h" - -#include "ppapi/cpp/core.h" -#include "ppapi/cpp/module.h" - -namespace chrome_pdf { - -Timer::Timer(base::TimeDelta delay) : delay_(delay), callback_factory_(this) { - PostCallback(); -} - -Timer::~Timer() = default; - -void Timer::PostCallback() { - pp::CompletionCallback callback = - callback_factory_.NewCallback(&Timer::TimerProc); - pp::Module::Get()->core()->CallOnMainThread(delay_.InMilliseconds(), callback, - 0); -} - -void Timer::TimerProc(int32_t /*result*/) { - PostCallback(); - OnTimer(); -} - -} // namespace chrome_pdf diff --git a/chromium/pdf/timer.h b/chromium/pdf/timer.h deleted file mode 100644 index cff2b88456a..00000000000 --- a/chromium/pdf/timer.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef PDF_TIMER_H_ -#define PDF_TIMER_H_ - -#include "base/macros.h" -#include "base/time/time.h" -#include "ppapi/utility/completion_callback_factory.h" - -namespace chrome_pdf { - -// Timer implementation for pepper plugins, based on pp::Core::CallOnMainThread. -// We can not use base::Timer for plugins, because they have no -// base::MessageLoop, on which it is based. -class Timer { - public: - explicit Timer(base::TimeDelta delay); - virtual ~Timer(); - - virtual void OnTimer() = 0; - - private: - void PostCallback(); - void TimerProc(int32_t result); - - const base::TimeDelta delay_; - pp::CompletionCallbackFactory<Timer> callback_factory_; - - DISALLOW_COPY_AND_ASSIGN(Timer); -}; - -} // namespace chrome_pdf - -#endif // PDF_TIMER_H_ diff --git a/chromium/pdf/url_loader_wrapper_impl.cc b/chromium/pdf/url_loader_wrapper_impl.cc index 050870ee281..f8d3163178c 100644 --- a/chromium/pdf/url_loader_wrapper_impl.cc +++ b/chromium/pdf/url_loader_wrapper_impl.cc @@ -10,7 +10,6 @@ #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "net/http/http_util.h" -#include "pdf/timer.h" #include "ppapi/c/pp_errors.h" #include "ppapi/cpp/logging.h" #include "ppapi/cpp/url_request_info.h" @@ -97,19 +96,6 @@ bool IsDoubleEndLineAtEnd(const char* buffer, int size) { } // namespace -class URLLoaderWrapperImpl::ReadStarter : public Timer { - public: - explicit ReadStarter(URLLoaderWrapperImpl* owner) - : Timer(kReadDelayMs), owner_(owner) {} - ~ReadStarter() override = default; - - // Timer overrides: - void OnTimer() override { owner_->ReadResponseBodyImpl(); } - - private: - URLLoaderWrapperImpl* owner_; -}; - URLLoaderWrapperImpl::URLLoaderWrapperImpl(pp::Instance* plugin_instance, const pp::URLLoader& url_loader) : plugin_instance_(plugin_instance), @@ -171,7 +157,7 @@ bool URLLoaderWrapperImpl::GetDownloadProgress( void URLLoaderWrapperImpl::Close() { url_loader_.Close(); - read_starter_.reset(); + read_starter_.Stop(); } void URLLoaderWrapperImpl::OpenRange(const std::string& url, @@ -195,11 +181,13 @@ void URLLoaderWrapperImpl::ReadResponseBody(char* buffer, did_read_callback_ = cc; buffer_ = buffer; buffer_size_ = buffer_size; - read_starter_ = std::make_unique<ReadStarter>(this); + read_starter_.Start( + FROM_HERE, kReadDelayMs, + base::BindRepeating(&URLLoaderWrapperImpl::ReadResponseBodyImpl, + base::Unretained(this))); } void URLLoaderWrapperImpl::ReadResponseBodyImpl() { - read_starter_.reset(); pp::CompletionCallback callback = callback_factory_.NewCallback(&URLLoaderWrapperImpl::DidRead); int rv = url_loader_.ReadResponseBody(buffer_, buffer_size_, callback); diff --git a/chromium/pdf/url_loader_wrapper_impl.h b/chromium/pdf/url_loader_wrapper_impl.h index e942e81182a..402c3f211ed 100644 --- a/chromium/pdf/url_loader_wrapper_impl.h +++ b/chromium/pdf/url_loader_wrapper_impl.h @@ -9,6 +9,7 @@ #include <string> #include "base/macros.h" +#include "base/timer/timer.h" #include "pdf/url_loader_wrapper.h" #include "ppapi/cpp/url_loader.h" #include "ppapi/utility/completion_callback_factory.h" @@ -50,8 +51,6 @@ class URLLoaderWrapperImpl : public URLLoaderWrapper { void SetResponseHeaders(const std::string& response_headers); private: - class ReadStarter; - void SetHeadersFromLoader(); void ParseHeaders(); void DidOpen(int32_t result); @@ -79,7 +78,7 @@ class URLLoaderWrapperImpl : public URLLoaderWrapper { pp::CompletionCallback did_read_callback_; pp::CompletionCallbackFactory<URLLoaderWrapperImpl> callback_factory_; - std::unique_ptr<ReadStarter> read_starter_; + base::OneShotTimer read_starter_; DISALLOW_COPY_AND_ASSIGN(URLLoaderWrapperImpl); }; |