#include "pdf/pdf_view_web_plugin.h"
#if defined(UNSAFE_BUFFERS_BUILD)
#pragma allow_unsafe_buffers
#endif
#include <stddef.h>
#include <stdint.h>
#include <algorithm>
#include <memory>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
#include "base/auto_reset.h"
#include "base/check_op.h"
#include "base/containers/fixed_flat_map.h"
#include "base/containers/queue.h"
#include "base/debug/crash_logging.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/i18n/char_iterator.h"
#include "base/i18n/rtl.h"
#include "base/i18n/string_search.h"
#include "base/i18n/time_formatting.h"
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/no_destructor.h"
#include "base/notreached.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/escape.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/thread_annotations.h"
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "base/values.h"
#include "cc/paint/paint_canvas.h"
#include "cc/paint/paint_flags.h"
#include "cc/paint/paint_image.h"
#include "cc/paint/paint_image_builder.h"
#include "net/cookies/site_for_cookies.h"
#include "pdf/accessibility.h"
#include "pdf/accessibility_structs.h"
#include "pdf/buildflags.h"
#include "pdf/content_restriction.h"
#include "pdf/document_layout.h"
#include "pdf/loader/result_codes.h"
#include "pdf/loader/url_loader.h"
#include "pdf/metrics_handler.h"
#include "pdf/mojom/pdf.mojom.h"
#include "pdf/paint_manager.h"
#include "pdf/paint_ready_rect.h"
#include "pdf/parsed_params.h"
#include "pdf/pdf_accessibility_data_handler.h"
#include "pdf/pdf_features.h"
#include "pdf/pdf_init.h"
#include "pdf/pdfium/pdfium_engine.h"
#include "pdf/pdfium/pdfium_engine_client.h"
#include "pdf/post_message_receiver.h"
#include "pdf/ui/document_properties.h"
#include "pdf/ui/file_name.h"
#include "pdf/ui/thumbnail.h"
#include "printing/metafile_skia.h"
#include "printing/units.h"
#include "services/network/public/mojom/referrer_policy.mojom-shared.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/input/web_coalesced_input_event.h"
#include "third_party/blink/public/common/input/web_input_event.h"
#include "third_party/blink/public/common/input/web_keyboard_event.h"
#include "third_party/blink/public/common/metrics/document_update_reason.h"
#include "third_party/blink/public/mojom/input/focus_type.mojom-shared.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_input_event_result.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_text_input_type.h"
#include "third_party/blink/public/platform/web_url.h"
#include "third_party/blink/public/platform/web_url_error.h"
#include "third_party/blink/public/platform/web_url_response.h"
#include "third_party/blink/public/web/web_associated_url_loader.h"
#include "third_party/blink/public/web/web_associated_url_loader_options.h"
#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_plugin_container.h"
#include "third_party/blink/public/web/web_plugin_params.h"
#include "third_party/blink/public/web/web_print_params.h"
#include "third_party/blink/public/web/web_print_preset_options.h"
#include "third_party/blink/public/web/web_view.h"
#include "third_party/blink/public/web/web_widget.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkImageInfo.h"
#include "third_party/skia/include/core/SkRect.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkSize.h"
#include "ui/base/cursor/cursor.h"
#include "ui/base/cursor/mojom/cursor_type.mojom-shared.h"
#include "ui/base/text/bytes_formatting.h"
#include "ui/events/base_event_utils.h"
#include "ui/events/blink/blink_event_util.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/point_conversions.h"
#include "ui/gfx/geometry/point_f.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/skia_conversions.h"
#include "ui/gfx/geometry/vector2d.h"
#include "ui/gfx/geometry/vector2d_f.h"
#include "ui/gfx/range/range.h"
#include "url/gurl.h"
#include "v8/include/v8.h"
#if BUILDFLAG(ENABLE_PDF_INK2)
#include "pdf/pdf_ink_module.h"
#endif
namespace chrome_pdf {
namespace {
constexpr double kMinZoom = …;
constexpr base::TimeDelta kAccessibilityPageDelay = …;
constexpr base::TimeDelta kFindResultCooldown = …;
constexpr std::string_view kChromeExtensionHost = …;
constexpr std::string_view kChromePrintHost = …;
constexpr std::string_view kChromeUntrustedPrintHost = …;
constexpr int kCompletePDFIndex = …;
constexpr int kInvalidPDFIndex = …;
enum class PinchPhase { … };
class PerProcessInitializer final { … };
base::Value::Dict DictFromRect(const gfx::Rect& rect) { … }
bool IsPrintPreviewUrl(std::string_view url) { … }
int ExtractPrintPreviewPageIndex(std::string_view src_url) { … }
bool IsPreviewingPDF(int print_preview_page_count) { … }
base::Value::Dict PrepareReplyMessage(std::string_view reply_type,
const base::Value::Dict& message) { … }
bool IsSaveDataSizeValid(size_t size) { … }
#if BUILDFLAG(ENABLE_PDF_INK2)
std::unique_ptr<PdfInkModule> MaybeCreatePdfInkModule(
PdfInkModule::Client& client) { … }
#endif
}
std::unique_ptr<PDFiumEngine> PdfViewWebPlugin::Client::CreateEngine(
PDFiumEngineClient* client,
PDFiumFormFiller::ScriptOption script_option) { … }
std::unique_ptr<PdfAccessibilityDataHandler>
PdfViewWebPlugin::Client::CreateAccessibilityDataHandler(
PdfAccessibilityActionHandler* action_handler,
PdfAccessibilityImageFetcher* image_fetcher,
blink::WebPluginContainer* plugin_container,
bool print_preview) { … }
PdfViewWebPlugin::PdfViewWebPlugin(
std::unique_ptr<Client> client,
mojo::AssociatedRemote<pdf::mojom::PdfHost> pdf_host,
blink::WebPluginParams params)
: … { … }
PdfViewWebPlugin::~PdfViewWebPlugin() = default;
bool PdfViewWebPlugin::Initialize(blink::WebPluginContainer* container) { … }
bool PdfViewWebPlugin::InitializeForTesting() { … }
bool PdfViewWebPlugin::InitializeCommon() { … }
void PdfViewWebPlugin::SendSetSmoothScrolling() { … }
void PdfViewWebPlugin::DidOpen(std::unique_ptr<UrlLoader> loader,
int32_t result) { … }
void PdfViewWebPlugin::Destroy() { … }
blink::WebPluginContainer* PdfViewWebPlugin::Container() const { … }
v8::Local<v8::Object> PdfViewWebPlugin::V8ScriptableObject(
v8::Isolate* isolate) { … }
bool PdfViewWebPlugin::SupportsKeyboardFocus() const { … }
void PdfViewWebPlugin::UpdateAllLifecyclePhases(
blink::DocumentUpdateReason reason) { … }
void PdfViewWebPlugin::Paint(cc::PaintCanvas* canvas, const gfx::Rect& rect) { … }
void PdfViewWebPlugin::UpdateGeometry(const gfx::Rect& window_rect,
const gfx::Rect& clip_rect,
const gfx::Rect& unobscured_rect,
bool is_visible) { … }
void PdfViewWebPlugin::UpdateScroll(const gfx::PointF& scroll_position) { … }
void PdfViewWebPlugin::UpdateFocus(bool focused,
blink::mojom::FocusType focus_type) { … }
void PdfViewWebPlugin::UpdateVisibility(bool visibility) { … }
blink::WebInputEventResult PdfViewWebPlugin::HandleInputEvent(
const blink::WebCoalescedInputEvent& event,
ui::Cursor* cursor) { … }
void PdfViewWebPlugin::DidReceiveResponse(
const blink::WebURLResponse& response) { … }
void PdfViewWebPlugin::DidReceiveData(const char* data, size_t data_length) { … }
void PdfViewWebPlugin::DidFinishLoading() { … }
void PdfViewWebPlugin::DidFailLoading(const blink::WebURLError& error) { … }
bool PdfViewWebPlugin::SupportsPaginatedPrint() { … }
bool PdfViewWebPlugin::GetPrintPresetOptionsFromDocument(
blink::WebPrintPresetOptions* print_preset_options) { … }
int PdfViewWebPlugin::PrintBegin(const blink::WebPrintParams& print_params) { … }
void PdfViewWebPlugin::PrintPage(int page_index, cc::PaintCanvas* canvas) { … }
void PdfViewWebPlugin::PrintEnd() { … }
bool PdfViewWebPlugin::HasSelection() const { … }
blink::WebString PdfViewWebPlugin::SelectionAsText() const { … }
blink::WebString PdfViewWebPlugin::SelectionAsMarkup() const { … }
bool PdfViewWebPlugin::CanEditText() const { … }
bool PdfViewWebPlugin::HasEditableText() const { … }
bool PdfViewWebPlugin::CanUndo() const { … }
bool PdfViewWebPlugin::CanRedo() const { … }
bool PdfViewWebPlugin::CanCopy() const { … }
bool PdfViewWebPlugin::ExecuteEditCommand(const blink::WebString& name,
const blink::WebString& value) { … }
blink::WebURL PdfViewWebPlugin::LinkAtPosition(
const gfx::Point& ) const { … }
bool PdfViewWebPlugin::StartFind(const blink::WebString& search_text,
bool case_sensitive,
int identifier) { … }
void PdfViewWebPlugin::SelectFindResult(bool forward, int identifier) { … }
void PdfViewWebPlugin::StopFind() { … }
bool PdfViewWebPlugin::CanRotateView() { … }
void PdfViewWebPlugin::RotateView(blink::WebPlugin::RotationType type) { … }
bool PdfViewWebPlugin::ShouldDispatchImeEventsToPlugin() { … }
blink::WebTextInputType PdfViewWebPlugin::GetPluginTextInputType() { … }
gfx::Rect PdfViewWebPlugin::GetPluginCaretBounds() { … }
void PdfViewWebPlugin::ImeSetCompositionForPlugin(
const blink::WebString& text,
const std::vector<ui::ImeTextSpan>& ,
const gfx::Range& ,
int ,
int ) { … }
void PdfViewWebPlugin::ImeCommitTextForPlugin(
const blink::WebString& text,
const std::vector<ui::ImeTextSpan>& ,
const gfx::Range& ,
int ) { … }
void PdfViewWebPlugin::ImeFinishComposingTextForPlugin(
bool ) { … }
void PdfViewWebPlugin::ProposeDocumentLayout(const DocumentLayout& layout) { … }
void PdfViewWebPlugin::Invalidate(const gfx::Rect& rect) { … }
void PdfViewWebPlugin::DidScroll(const gfx::Vector2d& offset) { … }
void PdfViewWebPlugin::ScrollToX(int x_screen_coords) { … }
void PdfViewWebPlugin::ScrollToY(int y_screen_coords) { … }
void PdfViewWebPlugin::ScrollBy(const gfx::Vector2d& delta) { … }
void PdfViewWebPlugin::ScrollToPage(int page) { … }
void PdfViewWebPlugin::NavigateTo(const std::string& url,
WindowOpenDisposition disposition) { … }
void PdfViewWebPlugin::NavigateToDestination(int page,
const float* x,
const float* y,
const float* zoom) { … }
void PdfViewWebPlugin::UpdateCursor(ui::mojom::CursorType new_cursor_type) { … }
void PdfViewWebPlugin::UpdateTickMarks(
const std::vector<gfx::Rect>& tickmarks) { … }
void PdfViewWebPlugin::NotifyNumberOfFindResultsChanged(int total,
bool final_result) { … }
void PdfViewWebPlugin::NotifySelectedFindResultChanged(int current_find_index,
bool final_result) { … }
void PdfViewWebPlugin::NotifyTouchSelectionOccurred() { … }
void PdfViewWebPlugin::CaretChanged(const gfx::Rect& caret_rect) { … }
void PdfViewWebPlugin::GetDocumentPassword(
base::OnceCallback<void(const std::string&)> callback) { … }
void PdfViewWebPlugin::Beep() { … }
void PdfViewWebPlugin::Alert(const std::string& message) { … }
bool PdfViewWebPlugin::Confirm(const std::string& message) { … }
std::string PdfViewWebPlugin::Prompt(const std::string& question,
const std::string& default_answer) { … }
std::string PdfViewWebPlugin::GetURL() { … }
void PdfViewWebPlugin::LoadUrl(std::string_view url, LoadUrlCallback callback) { … }
void PdfViewWebPlugin::Email(const std::string& to,
const std::string& cc,
const std::string& bcc,
const std::string& subject,
const std::string& body) { … }
void PdfViewWebPlugin::Print() { … }
void PdfViewWebPlugin::SubmitForm(const std::string& url,
const void* data,
int length) { … }
void PdfViewWebPlugin::DidFormOpen(int32_t result) { … }
void PdfViewWebPlugin::DidStartLoading() { … }
void PdfViewWebPlugin::DidStopLoading() { … }
int PdfViewWebPlugin::GetContentRestrictions() const { … }
std::unique_ptr<UrlLoader> PdfViewWebPlugin::CreateUrlLoader() { … }
v8::Isolate* PdfViewWebPlugin::GetIsolate() { … }
std::vector<PDFiumEngineClient::SearchStringResult>
PdfViewWebPlugin::SearchString(const char16_t* string,
const char16_t* term,
bool case_sensitive) { … }
void PdfViewWebPlugin::DocumentLoadComplete() { … }
void PdfViewWebPlugin::DocumentLoadFailed() { … }
void PdfViewWebPlugin::DocumentHasUnsupportedFeature(
const std::string& feature) { … }
void PdfViewWebPlugin::DocumentLoadProgress(uint32_t available,
uint32_t doc_size) { … }
void PdfViewWebPlugin::FormFieldFocusChange(
PDFiumEngineClient::FocusFieldType type) { … }
bool PdfViewWebPlugin::IsPrintPreview() const { … }
SkColor PdfViewWebPlugin::GetBackgroundColor() const { … }
void PdfViewWebPlugin::SelectionChanged(const gfx::Rect& left,
const gfx::Rect& right) { … }
void PdfViewWebPlugin::EnteredEditMode() { … }
void PdfViewWebPlugin::DocumentFocusChanged(bool document_has_focus) { … }
void PdfViewWebPlugin::SetSelectedText(const std::string& selected_text) { … }
void PdfViewWebPlugin::SetLinkUnderCursor(
const std::string& link_under_cursor) { … }
bool PdfViewWebPlugin::IsValidLink(const std::string& url) { … }
void PdfViewWebPlugin::SetCaretPosition(const gfx::PointF& position) { … }
void PdfViewWebPlugin::MoveRangeSelectionExtent(const gfx::PointF& extent) { … }
void PdfViewWebPlugin::SetSelectionBounds(const gfx::PointF& base,
const gfx::PointF& extent) { … }
bool PdfViewWebPlugin::IsValid() const { … }
blink::WebURL PdfViewWebPlugin::CompleteURL(
const blink::WebString& partial_url) const { … }
net::SiteForCookies PdfViewWebPlugin::SiteForCookies() const { … }
void PdfViewWebPlugin::SetReferrerForRequest(
blink::WebURLRequest& request,
const blink::WebURL& referrer_url) { … }
std::unique_ptr<blink::WebAssociatedURLLoader>
PdfViewWebPlugin::CreateAssociatedURLLoader(
const blink::WebAssociatedURLLoaderOptions& options) { … }
void PdfViewWebPlugin::OnMessage(const base::Value::Dict& message) { … }
void PdfViewWebPlugin::HandleDisplayAnnotationsMessage(
const base::Value::Dict& message) { … }
void PdfViewWebPlugin::HandleGetNamedDestinationMessage(
const base::Value::Dict& message) { … }
void PdfViewWebPlugin::HandleGetPageBoundingBoxMessage(
const base::Value::Dict& message) { … }
void PdfViewWebPlugin::HandleGetPasswordCompleteMessage(
const base::Value::Dict& message) { … }
void PdfViewWebPlugin::HandleGetSelectedTextMessage(
const base::Value::Dict& message) { … }
void PdfViewWebPlugin::HandleGetThumbnailMessage(
const base::Value::Dict& message) { … }
void PdfViewWebPlugin::HandlePrintMessage(
const base::Value::Dict& ) { … }
void PdfViewWebPlugin::HandleRotateClockwiseMessage(
const base::Value::Dict& ) { … }
void PdfViewWebPlugin::HandleRotateCounterclockwiseMessage(
const base::Value::Dict& ) { … }
void PdfViewWebPlugin::HandleSaveAttachmentMessage(
const base::Value::Dict& message) { … }
void PdfViewWebPlugin::HandleSaveMessage(const base::Value::Dict& message) { … }
void PdfViewWebPlugin::HandleSelectAllMessage(
const base::Value::Dict& ) { … }
void PdfViewWebPlugin::HandleSetBackgroundColorMessage(
const base::Value::Dict& message) { … }
void PdfViewWebPlugin::HandleSetPresentationModeMessage(
const base::Value::Dict& message) { … }
void PdfViewWebPlugin::HandleSetTwoUpViewMessage(
const base::Value::Dict& message) { … }
void PdfViewWebPlugin::HandleStopScrollingMessage(
const base::Value::Dict& ) { … }
void PdfViewWebPlugin::HandleViewportMessage(const base::Value::Dict& message) { … }
void PdfViewWebPlugin::SaveToBuffer(const std::string& token) { … }
void PdfViewWebPlugin::SaveToFile(const std::string& token) { … }
void PdfViewWebPlugin::InvalidatePluginContainer() { … }
void PdfViewWebPlugin::OnPaint(const std::vector<gfx::Rect>& paint_rects,
std::vector<PaintReadyRect>& ready,
std::vector<gfx::Rect>& pending) { … }
gfx::PointF PdfViewWebPlugin::GetScrollPositionFromOffset(
const gfx::Vector2dF& scroll_offset) const { … }
void PdfViewWebPlugin::DoPaint(const std::vector<gfx::Rect>& paint_rects,
std::vector<PaintReadyRect>& ready,
std::vector<gfx::Rect>& pending) { … }
void PdfViewWebPlugin::PrepareForFirstPaint(
std::vector<PaintReadyRect>& ready) { … }
void PdfViewWebPlugin::OnGeometryChanged(double old_zoom,
float old_device_scale) { … }
void PdfViewWebPlugin::RecalculateAreas(double old_zoom,
float old_device_scale) { … }
void PdfViewWebPlugin::CalculateBackgroundParts() { … }
int PdfViewWebPlugin::GetDocumentPixelWidth() const { … }
int PdfViewWebPlugin::GetDocumentPixelHeight() const { … }
void PdfViewWebPlugin::InvalidateAfterPaintDone() { … }
void PdfViewWebPlugin::ClearDeferredInvalidates() { … }
void PdfViewWebPlugin::UpdateSnapshot(sk_sp<SkImage> snapshot) { … }
void PdfViewWebPlugin::UpdateScaledValues() { … }
void PdfViewWebPlugin::UpdateScale(float scale) { … }
void PdfViewWebPlugin::UpdateLayerTransform(float scale,
const gfx::Vector2dF& translate) { … }
void PdfViewWebPlugin::EnableAccessibility() { … }
SkBitmap PdfViewWebPlugin::GetImageForOcr(int32_t page_index,
int32_t page_object_index) { … }
#if BUILDFLAG(ENABLE_PDF_INK2)
PageOrientation PdfViewWebPlugin::GetOrientation() const { … }
gfx::Rect PdfViewWebPlugin::GetPageContentsRect(int index) { … }
gfx::Vector2dF PdfViewWebPlugin::GetViewportOriginOffset() { … }
float PdfViewWebPlugin::GetZoom() const { … }
bool PdfViewWebPlugin::IsPageVisible(int page_index) { … }
void PdfViewWebPlugin::StrokeFinished() { … }
void PdfViewWebPlugin::UpdateInkCursorImage(SkBitmap bitmap) { … }
int PdfViewWebPlugin::VisiblePageIndexFromPoint(const gfx::PointF& point) { … }
#endif
void PdfViewWebPlugin::HandleAccessibilityAction(
const AccessibilityActionData& action_data) { … }
void PdfViewWebPlugin::LoadOrReloadAccessibility() { … }
void PdfViewWebPlugin::OnViewportChanged(
const gfx::Rect& new_plugin_rect_in_css_pixel,
float new_device_scale) { … }
bool PdfViewWebPlugin::SelectAll() { … }
bool PdfViewWebPlugin::Cut() { … }
bool PdfViewWebPlugin::Paste(const blink::WebString& value) { … }
bool PdfViewWebPlugin::Undo() { … }
bool PdfViewWebPlugin::Redo() { … }
bool PdfViewWebPlugin::HandleWebInputEvent(const blink::WebInputEvent& event) { … }
void PdfViewWebPlugin::HandleImeCommit(const blink::WebString& text) { … }
void PdfViewWebPlugin::OnInvokePrintDialog() { … }
void PdfViewWebPlugin::ResetRecentlySentFindUpdate() { … }
void PdfViewWebPlugin::RecordDocumentMetrics() { … }
void PdfViewWebPlugin::SendAttachments() { … }
void PdfViewWebPlugin::SendBookmarks() { … }
void PdfViewWebPlugin::SendExecutedEditCommand(std::string_view edit_command) { … }
void PdfViewWebPlugin::SendStartedFindInPage() { … }
void PdfViewWebPlugin::SendMetadata() { … }
void PdfViewWebPlugin::SendLoadingProgress(double percentage) { … }
void PdfViewWebPlugin::HandleResetPrintPreviewModeMessage(
const base::Value::Dict& message) { … }
void PdfViewWebPlugin::HandleLoadPreviewPageMessage(
const base::Value::Dict& message) { … }
void PdfViewWebPlugin::LoadAvailablePreviewPage() { … }
void PdfViewWebPlugin::DidOpenPreview(std::unique_ptr<UrlLoader> loader,
int32_t result) { … }
void PdfViewWebPlugin::PreviewDocumentLoadComplete() { … }
void PdfViewWebPlugin::PreviewDocumentLoadFailed() { … }
void PdfViewWebPlugin::LoadNextPreviewPage() { … }
void PdfViewWebPlugin::SendPrintPreviewLoadedNotification() { … }
void PdfViewWebPlugin::SendThumbnail(base::Value::Dict reply,
Thumbnail thumbnail) { … }
gfx::Point PdfViewWebPlugin::FrameToPdfCoordinates(
const gfx::PointF& frame_coordinates) const { … }
AccessibilityDocInfo PdfViewWebPlugin::GetAccessibilityDocInfo() const { … }
void PdfViewWebPlugin::PrepareAndSetAccessibilityPageInfo(int32_t page_index) { … }
void PdfViewWebPlugin::PrepareAndSetAccessibilityViewportInfo() { … }
void PdfViewWebPlugin::LoadAccessibility() { … }
}