[unseasoned-pdf] Implement Print Preview support.
Most of the CL is just moving lots of code out of OutOfProcessInstance and into PdfViewPluginBase. Then make a few tweaks to PdfViewWebPlugin to hook it up there. Along the way, address some pre-existing nits in the code being moved. Also remove PdfViewPluginBase::paint_manager() because it has no more external callers. Bug: 1140629 Change-Id: I6297e87525ff58bf8cc72feee2420563bdf1f34e Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2961851 Reviewed-by: Daniel Hosseinian <dhoss@chromium.org> Commit-Queue: Lei Zhang <thestig@chromium.org> Cr-Commit-Position: refs/heads/master@{#894377}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
fdc7b80a80
commit
d7f8698cf2
@ -21,7 +21,6 @@
|
||||
#include "base/notreached.h"
|
||||
#include "base/numerics/safe_conversions.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_split.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/time/time.h"
|
||||
#include "base/values.h"
|
||||
@ -76,10 +75,6 @@ namespace chrome_pdf {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr char kChromePrint[] = "chrome://print/";
|
||||
constexpr char kChromeExtension[] =
|
||||
"chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai";
|
||||
|
||||
// Constants used in handling postMessage() messages.
|
||||
constexpr char kType[] = "type";
|
||||
// Name of identifier field passed from JS to the plugin and back, to associate
|
||||
@ -91,24 +86,10 @@ constexpr char kJSAttachmentIndex[] = "attachmentIndex";
|
||||
// Save attachment data (Plugin -> Page)
|
||||
constexpr char kJSSaveAttachmentDataType[] = "saveAttachmentData";
|
||||
constexpr char kJSAttachmentDataToSave[] = "dataToSave";
|
||||
// Reset print preview mode (Page -> Plugin)
|
||||
constexpr char kJSResetPrintPreviewModeType[] = "resetPrintPreviewMode";
|
||||
constexpr char kJSPrintPreviewUrl[] = "url";
|
||||
constexpr char kJSPrintPreviewGrayscale[] = "grayscale";
|
||||
constexpr char kJSPrintPreviewPageCount[] = "pageCount";
|
||||
// Load preview page (Page -> Plugin)
|
||||
constexpr char kJSLoadPreviewPageType[] = "loadPreviewPage";
|
||||
constexpr char kJSPreviewPageUrl[] = "url";
|
||||
constexpr char kJSPreviewPageIndex[] = "index";
|
||||
|
||||
constexpr base::TimeDelta kFindResultCooldown =
|
||||
base::TimeDelta::FromMilliseconds(100);
|
||||
|
||||
// Same value as printing::COMPLETE_PREVIEW_DOCUMENT_INDEX.
|
||||
constexpr int kCompletePDFIndex = -1;
|
||||
// A different negative value to differentiate itself from `kCompletePDFIndex`.
|
||||
constexpr int kInvalidPDFIndex = -2;
|
||||
|
||||
constexpr char kPPPPdfInterface[] = PPP_PDF_INTERFACE_1;
|
||||
|
||||
PP_Var GetLinkAtPosition(PP_Instance instance, PP_Point point) {
|
||||
@ -314,32 +295,6 @@ const PPP_Pdf ppp_private = {
|
||||
&PdfPrintBegin,
|
||||
};
|
||||
|
||||
int ExtractPrintPreviewPageIndex(base::StringPiece src_url) {
|
||||
// Sample `src_url` format: chrome://print/id/page_index/print.pdf
|
||||
// The page_index is zero-based, but can be negative with special meanings.
|
||||
std::vector<base::StringPiece> url_substr =
|
||||
base::SplitStringPiece(src_url.substr(strlen(kChromePrint)), "/",
|
||||
base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
|
||||
if (url_substr.size() != 3)
|
||||
return kInvalidPDFIndex;
|
||||
|
||||
if (url_substr[2] != "print.pdf")
|
||||
return kInvalidPDFIndex;
|
||||
|
||||
int page_index = 0;
|
||||
if (!base::StringToInt(url_substr[1], &page_index))
|
||||
return kInvalidPDFIndex;
|
||||
return page_index;
|
||||
}
|
||||
|
||||
bool IsPrintPreviewUrl(base::StringPiece url) {
|
||||
return base::StartsWith(url, kChromePrint);
|
||||
}
|
||||
|
||||
bool IsPreviewingPDF(int print_preview_page_count) {
|
||||
return print_preview_page_count == 0;
|
||||
}
|
||||
|
||||
void ScalePoint(float scale, pp::Point* point) {
|
||||
point->set_x(static_cast<int>(point->x() * scale));
|
||||
point->set_y(static_cast<int>(point->y() * scale));
|
||||
@ -483,6 +438,7 @@ OutOfProcessInstance::~OutOfProcessInstance() {
|
||||
RemovePerInstanceObject(kPPPPdfInterface, this);
|
||||
// Explicitly destroy the PDFEngine during destruction as it may call back
|
||||
// into this object.
|
||||
DestroyPreviewEngine();
|
||||
DestroyEngine();
|
||||
}
|
||||
|
||||
@ -504,9 +460,8 @@ bool OutOfProcessInstance::Init(uint32_t argc,
|
||||
// a CHECK as a defense-in-depth.
|
||||
std::string document_url = document_url_var.AsString();
|
||||
base::StringPiece document_url_piece(document_url);
|
||||
is_print_preview_ = IsPrintPreviewUrl(document_url_piece);
|
||||
CHECK(base::StartsWith(document_url_piece, kChromeExtension) ||
|
||||
is_print_preview_);
|
||||
set_is_print_preview(IsPrintPreviewUrl(document_url_piece));
|
||||
ValidateDocumentUrl(document_url_piece);
|
||||
|
||||
// Allow the plugin to handle find requests.
|
||||
SetPluginToHandleFindRequests();
|
||||
@ -585,10 +540,6 @@ void OutOfProcessInstance::HandleMessage(const pp::Var& message) {
|
||||
|
||||
if (type == kJSSaveAttachmentType) {
|
||||
HandleSaveAttachmentMessage(dict);
|
||||
} else if (type == kJSResetPrintPreviewModeType) {
|
||||
HandleResetPrintPreviewModeMessage(dict);
|
||||
} else if (type == kJSLoadPreviewPageType) {
|
||||
HandleLoadPreviewPageMessage(dict);
|
||||
} else {
|
||||
PdfViewPluginBase::HandleMessage(ValueFromVar(message));
|
||||
}
|
||||
@ -606,7 +557,7 @@ void OutOfProcessInstance::DidChangeView(const pp::View& view) {
|
||||
UpdateGeometryOnViewChanged(RectFromPPRect(view.GetRect()),
|
||||
view.GetDeviceScale());
|
||||
|
||||
if (is_print_preview_ && !stop_scrolling()) {
|
||||
if (IsPrintPreview() && !stop_scrolling()) {
|
||||
set_scroll_position(PointFromPPPoint(view.GetScrollOffset()));
|
||||
UpdateScroll();
|
||||
}
|
||||
@ -767,18 +718,6 @@ void OutOfProcessInstance::DidOpen(std::unique_ptr<UrlLoader> loader,
|
||||
}
|
||||
}
|
||||
|
||||
void OutOfProcessInstance::DidOpenPreview(std::unique_ptr<UrlLoader> loader,
|
||||
int32_t result) {
|
||||
if (result == PP_OK) {
|
||||
preview_client_ = std::make_unique<PreviewModeClient>(this);
|
||||
preview_engine_ = std::make_unique<PDFiumEngine>(
|
||||
preview_client_.get(), PDFiumFormFiller::ScriptOption::kNoJavaScript);
|
||||
preview_engine_->HandleDocumentLoad(std::move(loader));
|
||||
} else {
|
||||
NOTREACHED();
|
||||
}
|
||||
}
|
||||
|
||||
void OutOfProcessInstance::SendMessage(base::Value message) {
|
||||
PostMessage(VarFromValue(message));
|
||||
}
|
||||
@ -926,72 +865,6 @@ void OutOfProcessInstance::RotateCounterclockwise() {
|
||||
engine()->RotateCounterclockwise();
|
||||
}
|
||||
|
||||
void OutOfProcessInstance::HandleLoadPreviewPageMessage(
|
||||
const pp::VarDictionary& dict) {
|
||||
if (!(dict.Get(pp::Var(kJSPreviewPageUrl)).is_string() &&
|
||||
dict.Get(pp::Var(kJSPreviewPageIndex)).is_int())) {
|
||||
NOTREACHED();
|
||||
return;
|
||||
}
|
||||
|
||||
std::string url = dict.Get(pp::Var(kJSPreviewPageUrl)).AsString();
|
||||
// For security reasons we crash if the URL that is trying to be loaded here
|
||||
// isn't a print preview one.
|
||||
CHECK(IsPrintPreview());
|
||||
CHECK(IsPrintPreviewUrl(url));
|
||||
ProcessPreviewPageInfo(url, dict.Get(pp::Var(kJSPreviewPageIndex)).AsInt());
|
||||
}
|
||||
|
||||
void OutOfProcessInstance::HandleResetPrintPreviewModeMessage(
|
||||
const pp::VarDictionary& dict) {
|
||||
if (!(dict.Get(pp::Var(kJSPrintPreviewUrl)).is_string() &&
|
||||
dict.Get(pp::Var(kJSPrintPreviewGrayscale)).is_bool() &&
|
||||
dict.Get(pp::Var(kJSPrintPreviewPageCount)).is_int())) {
|
||||
NOTREACHED();
|
||||
return;
|
||||
}
|
||||
|
||||
// For security reasons, crash if the URL that is trying to be loaded here
|
||||
// isn't a print preview one.
|
||||
std::string url = dict.Get(pp::Var(kJSPrintPreviewUrl)).AsString();
|
||||
CHECK(IsPrintPreview());
|
||||
CHECK(IsPrintPreviewUrl(url));
|
||||
|
||||
int print_preview_page_count =
|
||||
dict.Get(pp::Var(kJSPrintPreviewPageCount)).AsInt();
|
||||
if (print_preview_page_count < 0) {
|
||||
NOTREACHED();
|
||||
return;
|
||||
}
|
||||
|
||||
// The page count is zero if the print preview source is a PDF. In which
|
||||
// case, the page index for `url` should be at `kCompletePDFIndex`.
|
||||
// When the page count is not zero, then the source is not PDF. In which
|
||||
// case, the page index for `url` should be non-negative.
|
||||
bool is_previewing_pdf = IsPreviewingPDF(print_preview_page_count);
|
||||
int page_index = ExtractPrintPreviewPageIndex(url);
|
||||
if ((is_previewing_pdf && page_index != kCompletePDFIndex) ||
|
||||
(!is_previewing_pdf && page_index < 0)) {
|
||||
NOTREACHED();
|
||||
return;
|
||||
}
|
||||
|
||||
print_preview_page_count_ = print_preview_page_count;
|
||||
print_preview_loaded_page_count_ = 0;
|
||||
set_url(url);
|
||||
preview_pages_info_ = base::queue<PreviewPageInfo>();
|
||||
preview_document_load_state_ = DocumentLoadState::kComplete;
|
||||
set_document_load_state(DocumentLoadState::kLoading);
|
||||
LoadUrl(GetURL(), /*is_print_preview=*/false);
|
||||
preview_engine_.reset();
|
||||
InitializeEngine(std::make_unique<PDFiumEngine>(
|
||||
this, PDFiumFormFiller::ScriptOption::kNoJavaScript));
|
||||
engine()->SetGrayscale(dict.Get(pp::Var(kJSPrintPreviewGrayscale)).AsBool());
|
||||
engine()->New(GetURL().c_str(), /*headers=*/nullptr);
|
||||
|
||||
paint_manager().InvalidateRect(gfx::Rect(plugin_rect().size()));
|
||||
}
|
||||
|
||||
void OutOfProcessInstance::HandleSaveAttachmentMessage(
|
||||
const pp::VarDictionary& dict) {
|
||||
if (!dict.Get(pp::Var(kJSMessageId)).is_string() ||
|
||||
@ -1030,38 +903,6 @@ void OutOfProcessInstance::HandleSaveAttachmentMessage(
|
||||
PostMessage(message);
|
||||
}
|
||||
|
||||
void OutOfProcessInstance::PreviewDocumentLoadComplete() {
|
||||
if (preview_document_load_state_ != DocumentLoadState::kLoading ||
|
||||
preview_pages_info_.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
preview_document_load_state_ = DocumentLoadState::kComplete;
|
||||
|
||||
int dest_page_index = preview_pages_info_.front().second;
|
||||
DCHECK_GT(dest_page_index, 0);
|
||||
preview_pages_info_.pop();
|
||||
DCHECK(preview_engine_);
|
||||
engine()->AppendPage(preview_engine_.get(), dest_page_index);
|
||||
|
||||
++print_preview_loaded_page_count_;
|
||||
LoadNextPreviewPage();
|
||||
}
|
||||
|
||||
void OutOfProcessInstance::PreviewDocumentLoadFailed() {
|
||||
UserMetricsRecordAction("PDF.PreviewDocumentLoadFailure");
|
||||
if (preview_document_load_state_ != DocumentLoadState::kLoading ||
|
||||
preview_pages_info_.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Even if a print preview page failed to load, keep going.
|
||||
preview_document_load_state_ = DocumentLoadState::kFailed;
|
||||
preview_pages_info_.pop();
|
||||
++print_preview_loaded_page_count_;
|
||||
LoadNextPreviewPage();
|
||||
}
|
||||
|
||||
pp::Instance* OutOfProcessInstance::GetPluginInstance() {
|
||||
return this;
|
||||
}
|
||||
@ -1131,15 +972,6 @@ std::unique_ptr<UrlLoader> OutOfProcessInstance::CreateUrlLoaderInternal() {
|
||||
return loader;
|
||||
}
|
||||
|
||||
void OutOfProcessInstance::AppendBlankPrintPreviewPages() {
|
||||
engine()->AppendBlankPages(print_preview_page_count_);
|
||||
LoadNextPreviewPage();
|
||||
}
|
||||
|
||||
bool OutOfProcessInstance::IsPrintPreview() {
|
||||
return is_print_preview_;
|
||||
}
|
||||
|
||||
void OutOfProcessInstance::SetSelectedText(const std::string& selected_text) {
|
||||
pp::PDF::SetSelectedText(this, selected_text.c_str());
|
||||
}
|
||||
@ -1176,55 +1008,6 @@ void OutOfProcessInstance::ScheduleTaskOnMainThread(
|
||||
PPCompletionCallbackFromResultCallback(std::move(callback)), result);
|
||||
}
|
||||
|
||||
void OutOfProcessInstance::ProcessPreviewPageInfo(const std::string& url,
|
||||
int dest_page_index) {
|
||||
DCHECK(IsPrintPreview());
|
||||
|
||||
if (dest_page_index < 0 || dest_page_index >= print_preview_page_count_) {
|
||||
NOTREACHED();
|
||||
return;
|
||||
}
|
||||
|
||||
// Print Preview JS will send the loadPreviewPage message for every page,
|
||||
// including the first page in the print preview, which has already been
|
||||
// loaded when handing the resetPrintPreviewMode message. Just ignore it.
|
||||
if (dest_page_index == 0)
|
||||
return;
|
||||
|
||||
int src_page_index = ExtractPrintPreviewPageIndex(url);
|
||||
if (src_page_index < 0) {
|
||||
NOTREACHED();
|
||||
return;
|
||||
}
|
||||
|
||||
preview_pages_info_.push(std::make_pair(url, dest_page_index));
|
||||
LoadAvailablePreviewPage();
|
||||
}
|
||||
|
||||
void OutOfProcessInstance::LoadAvailablePreviewPage() {
|
||||
if (preview_pages_info_.empty() ||
|
||||
document_load_state() != DocumentLoadState::kComplete ||
|
||||
preview_document_load_state_ == DocumentLoadState::kLoading) {
|
||||
return;
|
||||
}
|
||||
|
||||
preview_document_load_state_ = DocumentLoadState::kLoading;
|
||||
const std::string& url = preview_pages_info_.front().first;
|
||||
LoadUrl(url, /*is_print_preview=*/true);
|
||||
}
|
||||
|
||||
void OutOfProcessInstance::LoadNextPreviewPage() {
|
||||
if (!preview_pages_info_.empty()) {
|
||||
DCHECK_LT(print_preview_loaded_page_count_, print_preview_page_count_);
|
||||
LoadAvailablePreviewPage();
|
||||
return;
|
||||
}
|
||||
|
||||
if (print_preview_loaded_page_count_ == print_preview_page_count_) {
|
||||
SendPrintPreviewLoadedNotification();
|
||||
}
|
||||
}
|
||||
|
||||
void OutOfProcessInstance::DidStartLoading() {
|
||||
if (did_call_start_loading_)
|
||||
return;
|
||||
@ -1241,19 +1024,6 @@ void OutOfProcessInstance::DidStopLoading() {
|
||||
did_call_start_loading_ = false;
|
||||
}
|
||||
|
||||
void OutOfProcessInstance::OnPrintPreviewLoaded() {
|
||||
// Scroll location is retained across document loads in print preview mode, so
|
||||
// there's no need to override the scroll position by scrolling again.
|
||||
if (IsPreviewingPDF(print_preview_page_count_)) {
|
||||
SendPrintPreviewLoadedNotification();
|
||||
} else {
|
||||
DCHECK_EQ(0, print_preview_loaded_page_count_);
|
||||
print_preview_loaded_page_count_ = 1;
|
||||
AppendBlankPrintPreviewPages();
|
||||
}
|
||||
OnGeometryChanged(0, 0);
|
||||
}
|
||||
|
||||
void OutOfProcessInstance::InvokePrintDialog() {
|
||||
pp::PDF::Print(this);
|
||||
}
|
||||
|
@ -10,14 +10,11 @@
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "base/containers/queue.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "pdf/pdf_view_plugin_base.h"
|
||||
#include "pdf/preview_mode_client.h"
|
||||
#include "ppapi/c/private/ppp_pdf.h"
|
||||
#include "ppapi/cpp/dev/printing_dev.h"
|
||||
#include "ppapi/cpp/image_data.h"
|
||||
@ -39,14 +36,12 @@ class VarDictionary;
|
||||
namespace chrome_pdf {
|
||||
|
||||
class Graphics;
|
||||
class PDFiumEngine;
|
||||
class UrlLoader;
|
||||
|
||||
class OutOfProcessInstance : public PdfViewPluginBase,
|
||||
public pp::Instance,
|
||||
public pp::Find_Private,
|
||||
public pp::Printing_Dev,
|
||||
public PreviewModeClient::Client {
|
||||
public pp::Printing_Dev {
|
||||
public:
|
||||
explicit OutOfProcessInstance(PP_Instance instance);
|
||||
OutOfProcessInstance(const OutOfProcessInstance&) = delete;
|
||||
@ -109,7 +104,6 @@ class OutOfProcessInstance : public PdfViewPluginBase,
|
||||
const char16_t* term,
|
||||
bool case_sensitive) override;
|
||||
pp::Instance* GetPluginInstance() override;
|
||||
bool IsPrintPreview() override;
|
||||
void SetSelectedText(const std::string& selected_text) override;
|
||||
void SetLinkUnderCursor(const std::string& link_under_cursor) override;
|
||||
bool IsValidLink(const std::string& url) override;
|
||||
@ -120,10 +114,6 @@ class OutOfProcessInstance : public PdfViewPluginBase,
|
||||
int32_t result,
|
||||
base::TimeDelta delay) override;
|
||||
|
||||
// PreviewModeClient::Client:
|
||||
void PreviewDocumentLoadComplete() override;
|
||||
void PreviewDocumentLoadFailed() override;
|
||||
|
||||
// Helper functions for implementing PPP_PDF.
|
||||
void RotateClockwise();
|
||||
void RotateCounterclockwise();
|
||||
@ -133,8 +123,6 @@ class OutOfProcessInstance : public PdfViewPluginBase,
|
||||
base::WeakPtr<PdfViewPluginBase> GetWeakPtr() override;
|
||||
std::unique_ptr<UrlLoader> CreateUrlLoaderInternal() override;
|
||||
void DidOpen(std::unique_ptr<UrlLoader> loader, int32_t result) override;
|
||||
void DidOpenPreview(std::unique_ptr<UrlLoader> loader,
|
||||
int32_t result) override;
|
||||
void SendMessage(base::Value message) override;
|
||||
void SaveAs() override;
|
||||
void InitImageData(const gfx::Size& size) override;
|
||||
@ -152,7 +140,6 @@ class OutOfProcessInstance : public PdfViewPluginBase,
|
||||
void DidStartLoading() override;
|
||||
void DidStopLoading() override;
|
||||
void InvokePrintDialog() override;
|
||||
void OnPrintPreviewLoaded() override;
|
||||
void NotifySelectionChanged(const gfx::PointF& left,
|
||||
int left_height,
|
||||
const gfx::PointF& right,
|
||||
@ -162,8 +149,6 @@ class OutOfProcessInstance : public PdfViewPluginBase,
|
||||
|
||||
private:
|
||||
// Message handlers.
|
||||
void HandleLoadPreviewPageMessage(const pp::VarDictionary& dict);
|
||||
void HandleResetPrintPreviewModeMessage(const pp::VarDictionary& dict);
|
||||
void HandleSaveAttachmentMessage(const pp::VarDictionary& dict);
|
||||
|
||||
void ResetRecentlySentFindUpdate(int32_t);
|
||||
@ -172,59 +157,12 @@ class OutOfProcessInstance : public PdfViewPluginBase,
|
||||
|
||||
void FormDidOpen(int32_t result);
|
||||
|
||||
// Reduces the document to 1 page and appends `print_preview_page_count_` - 1
|
||||
// blank pages to the document for print preview.
|
||||
void AppendBlankPrintPreviewPages();
|
||||
|
||||
// Process the preview page data information. `src_url` specifies the preview
|
||||
// page data location. The `src_url` is in the format:
|
||||
// chrome://print/id/page_number/print.pdf
|
||||
// `dest_page_index` specifies the blank page index that needs to be replaced
|
||||
// with the new page data.
|
||||
void ProcessPreviewPageInfo(const std::string& src_url, int dest_page_index);
|
||||
// Load the next available preview page into the blank page.
|
||||
void LoadAvailablePreviewPage();
|
||||
|
||||
// Called after a preview page has loaded or failed to load.
|
||||
void LoadNextPreviewPage();
|
||||
|
||||
// The Pepper image data that is in sync with mutable_image_data().
|
||||
pp::ImageData pepper_image_data_;
|
||||
|
||||
// The PreviewModeClient used for print preview. Will be passed to
|
||||
// `preview_engine_`.
|
||||
std::unique_ptr<PreviewModeClient> preview_client_;
|
||||
|
||||
// This engine is used to render the individual preview page data. This is
|
||||
// used only in print preview mode. This will use `PreviewModeClient`
|
||||
// interface which has very limited access to the pp::Instance.
|
||||
std::unique_ptr<PDFiumEngine> preview_engine_;
|
||||
|
||||
// Used for submitting forms.
|
||||
std::unique_ptr<UrlLoader> form_loader_;
|
||||
|
||||
DocumentLoadState preview_document_load_state_ = DocumentLoadState::kComplete;
|
||||
|
||||
// True if the plugin is loaded in print preview, otherwise false.
|
||||
bool is_print_preview_ = false;
|
||||
|
||||
// Number of pages in print preview mode for non-PDF source, 0 if print
|
||||
// previewing a PDF, and -1 if not in print preview mode.
|
||||
int print_preview_page_count_ = -1;
|
||||
|
||||
// Number of pages loaded in print preview mode for non-PDF source. Always
|
||||
// less than or equal to `print_preview_page_count_`.
|
||||
int print_preview_loaded_page_count_ = -1;
|
||||
|
||||
// Used to manage loaded print preview page information. A `PreviewPageInfo`
|
||||
// consists of data source URL string and the page index in the destination
|
||||
// document.
|
||||
// The URL string embeds a page number that can be found with
|
||||
// ExtractPrintPreviewPageIndex(). This page number is always greater than 0.
|
||||
// The page index is always in the range of [0, print_preview_page_count_).
|
||||
using PreviewPageInfo = std::pair<std::string, int>;
|
||||
base::queue<PreviewPageInfo> preview_pages_info_;
|
||||
|
||||
// Used to signal the browser about focus changes to trigger the OSK.
|
||||
// TODO(abodenha@chromium.org) Implement full IME support in the plugin.
|
||||
// http://crbug.com/132565
|
||||
|
@ -28,7 +28,9 @@
|
||||
#include "base/notreached.h"
|
||||
#include "base/numerics/ranges.h"
|
||||
#include "base/numerics/safe_conversions.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_piece.h"
|
||||
#include "base/strings/string_split.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/time/time.h"
|
||||
#include "base/values.h"
|
||||
@ -76,6 +78,15 @@ constexpr double kMinZoom = 0.01;
|
||||
constexpr base::TimeDelta kAccessibilityPageDelay =
|
||||
base::TimeDelta::FromMilliseconds(100);
|
||||
|
||||
constexpr char kChromePrintHost[] = "chrome://print/";
|
||||
constexpr char kChromeExtensionHost[] =
|
||||
"chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai";
|
||||
|
||||
// Same value as printing::COMPLETE_PREVIEW_DOCUMENT_INDEX.
|
||||
constexpr int kCompletePDFIndex = -1;
|
||||
// A different negative value to differentiate itself from `kCompletePDFIndex`.
|
||||
constexpr int kInvalidPDFIndex = -2;
|
||||
|
||||
// Enumeration of pinch states.
|
||||
// This should match PinchPhase enum in chrome/browser/resources/pdf/viewport.js
|
||||
enum class PinchPhase {
|
||||
@ -100,6 +111,28 @@ base::Value PrepareReplyMessage(base::StringPiece reply_type,
|
||||
return reply;
|
||||
}
|
||||
|
||||
int ExtractPrintPreviewPageIndex(base::StringPiece src_url) {
|
||||
// Sample `src_url` format: chrome://print/id/page_index/print.pdf
|
||||
// The page_index is zero-based, but can be negative with special meanings.
|
||||
std::vector<base::StringPiece> url_substr =
|
||||
base::SplitStringPiece(src_url.substr(strlen(kChromePrintHost)), "/",
|
||||
base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
|
||||
if (url_substr.size() != 3)
|
||||
return kInvalidPDFIndex;
|
||||
|
||||
if (url_substr[2] != "print.pdf")
|
||||
return kInvalidPDFIndex;
|
||||
|
||||
int page_index = 0;
|
||||
if (!base::StringToInt(url_substr[1], &page_index))
|
||||
return kInvalidPDFIndex;
|
||||
return page_index;
|
||||
}
|
||||
|
||||
bool IsPreviewingPDF(int print_preview_page_count) {
|
||||
return print_preview_page_count == 0;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
PdfViewPluginBase::PdfViewPluginBase() = default;
|
||||
@ -379,6 +412,10 @@ void PdfViewPluginBase::FormTextFieldFocusChange(bool in_focus) {
|
||||
SetFormFieldInFocus(in_focus);
|
||||
}
|
||||
|
||||
bool PdfViewPluginBase::IsPrintPreview() {
|
||||
return is_print_preview_;
|
||||
}
|
||||
|
||||
SkColor PdfViewPluginBase::GetBackgroundColor() {
|
||||
return background_color_;
|
||||
}
|
||||
@ -470,6 +507,9 @@ void PdfViewPluginBase::HandleMessage(const base::Value& message) {
|
||||
{"getSelectedText", &PdfViewPluginBase::HandleGetSelectedTextMessage},
|
||||
{"getThumbnail", &PdfViewPluginBase::HandleGetThumbnailMessage},
|
||||
{"print", &PdfViewPluginBase::HandlePrintMessage},
|
||||
{"loadPreviewPage", &PdfViewPluginBase::HandleLoadPreviewPageMessage},
|
||||
{"resetPrintPreviewMode",
|
||||
&PdfViewPluginBase::HandleResetPrintPreviewModeMessage},
|
||||
{"rotateClockwise", &PdfViewPluginBase::HandleRotateClockwiseMessage},
|
||||
{"rotateCounterclockwise",
|
||||
&PdfViewPluginBase::HandleRotateCounterclockwiseMessage},
|
||||
@ -555,6 +595,38 @@ void PdfViewPluginBase::OnPaint(const std::vector<gfx::Rect>& paint_rects,
|
||||
DoPaint(paint_rects, ready, pending);
|
||||
}
|
||||
|
||||
void PdfViewPluginBase::PreviewDocumentLoadComplete() {
|
||||
if (preview_document_load_state_ != DocumentLoadState::kLoading ||
|
||||
preview_pages_info_.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
preview_document_load_state_ = DocumentLoadState::kComplete;
|
||||
|
||||
int dest_page_index = preview_pages_info_.front().second;
|
||||
DCHECK_GT(dest_page_index, 0);
|
||||
preview_pages_info_.pop();
|
||||
DCHECK(preview_engine_);
|
||||
engine()->AppendPage(preview_engine_.get(), dest_page_index);
|
||||
|
||||
++print_preview_loaded_page_count_;
|
||||
LoadNextPreviewPage();
|
||||
}
|
||||
|
||||
void PdfViewPluginBase::PreviewDocumentLoadFailed() {
|
||||
UserMetricsRecordAction("PDF.PreviewDocumentLoadFailure");
|
||||
if (preview_document_load_state_ != DocumentLoadState::kLoading ||
|
||||
preview_pages_info_.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Even if a print preview page failed to load, keep going.
|
||||
preview_document_load_state_ = DocumentLoadState::kFailed;
|
||||
preview_pages_info_.pop();
|
||||
++print_preview_loaded_page_count_;
|
||||
LoadNextPreviewPage();
|
||||
}
|
||||
|
||||
void PdfViewPluginBase::EnableAccessibility() {
|
||||
if (accessibility_state_ == AccessibilityState::kLoaded)
|
||||
return;
|
||||
@ -585,6 +657,15 @@ void PdfViewPluginBase::DestroyEngine() {
|
||||
engine_.reset();
|
||||
}
|
||||
|
||||
void PdfViewPluginBase::DestroyPreviewEngine() {
|
||||
preview_engine_.reset();
|
||||
}
|
||||
|
||||
void PdfViewPluginBase::ValidateDocumentUrl(base::StringPiece document_url) {
|
||||
CHECK(base::StartsWith(document_url, kChromeExtensionHost) ||
|
||||
IsPrintPreview());
|
||||
}
|
||||
|
||||
void PdfViewPluginBase::LoadUrl(const std::string& url, bool is_print_preview) {
|
||||
UrlRequest request;
|
||||
request.url = url;
|
||||
@ -678,7 +759,7 @@ void PdfViewPluginBase::UpdateGeometryOnViewChanged(
|
||||
plugin_rect_ = new_plugin_rect;
|
||||
plugin_dip_size_ = new_view_rect.size();
|
||||
|
||||
paint_manager().SetSize(plugin_rect_.size(), device_scale_);
|
||||
paint_manager_.SetSize(plugin_rect_.size(), device_scale_);
|
||||
|
||||
// Initialize the image data buffer if the context size changes.
|
||||
const gfx::Size old_image_size = gfx::SkISizeToSize(image_data_.dimensions());
|
||||
@ -839,6 +920,11 @@ void PdfViewPluginBase::SetZoom(double scale) {
|
||||
OnGeometryChanged(old_zoom, device_scale_);
|
||||
}
|
||||
|
||||
// static
|
||||
bool PdfViewPluginBase::IsPrintPreviewUrl(base::StringPiece url) {
|
||||
return base::StartsWith(url, kChromePrintHost);
|
||||
}
|
||||
|
||||
void PdfViewPluginBase::HandleDisplayAnnotationsMessage(
|
||||
const base::Value& message) {
|
||||
engine()->DisplayAnnotations(message.FindBoolKey("display").value());
|
||||
@ -898,10 +984,59 @@ void PdfViewPluginBase::HandleGetThumbnailMessage(const base::Value& message) {
|
||||
GetWeakPtr(), std::move(reply)));
|
||||
}
|
||||
|
||||
void PdfViewPluginBase::HandleLoadPreviewPageMessage(
|
||||
const base::Value& message) {
|
||||
const std::string& url = *message.FindStringKey("url");
|
||||
int index = message.FindIntKey("index").value();
|
||||
|
||||
// For security reasons, crash if `url` is not for Print Preview.
|
||||
CHECK(IsPrintPreview());
|
||||
CHECK(IsPrintPreviewUrl(url));
|
||||
ProcessPreviewPageInfo(url, index);
|
||||
}
|
||||
|
||||
void PdfViewPluginBase::HandlePrintMessage(const base::Value& /*message*/) {
|
||||
Print();
|
||||
}
|
||||
|
||||
void PdfViewPluginBase::HandleResetPrintPreviewModeMessage(
|
||||
const base::Value& message) {
|
||||
const std::string& url = *message.FindStringKey("url");
|
||||
bool is_grayscale = message.FindBoolKey("grayscale").value();
|
||||
int print_preview_page_count = message.FindIntKey("pageCount").value();
|
||||
|
||||
// For security reasons, crash if `url` is not for Print Preview.
|
||||
CHECK(IsPrintPreview());
|
||||
CHECK(IsPrintPreviewUrl(url));
|
||||
DCHECK_GE(print_preview_page_count, 0);
|
||||
|
||||
// The page count is zero if the print preview source is a PDF. In which
|
||||
// case, the page index for `url` should be at `kCompletePDFIndex`.
|
||||
// When the page count is not zero, then the source is not PDF. In which
|
||||
// case, the page index for `url` should be non-negative.
|
||||
bool is_previewing_pdf = IsPreviewingPDF(print_preview_page_count);
|
||||
int page_index = ExtractPrintPreviewPageIndex(url);
|
||||
if (is_previewing_pdf)
|
||||
DCHECK_EQ(page_index, kCompletePDFIndex);
|
||||
else
|
||||
DCHECK_GE(page_index, 0);
|
||||
|
||||
print_preview_page_count_ = print_preview_page_count;
|
||||
print_preview_loaded_page_count_ = 0;
|
||||
url_ = url;
|
||||
preview_pages_info_ = base::queue<PreviewPageInfo>();
|
||||
preview_document_load_state_ = DocumentLoadState::kComplete;
|
||||
document_load_state_ = DocumentLoadState::kLoading;
|
||||
LoadUrl(GetURL(), /*is_print_preview=*/false);
|
||||
preview_engine_.reset();
|
||||
InitializeEngine(std::make_unique<PDFiumEngine>(
|
||||
this, PDFiumFormFiller::ScriptOption::kNoJavaScript));
|
||||
engine()->SetGrayscale(is_grayscale);
|
||||
engine()->New(GetURL().c_str(), /*headers=*/nullptr);
|
||||
|
||||
paint_manager_.InvalidateRect(gfx::Rect(plugin_rect().size()));
|
||||
}
|
||||
|
||||
void PdfViewPluginBase::HandleRotateClockwiseMessage(
|
||||
const base::Value& /*message*/) {
|
||||
engine()->RotateClockwise();
|
||||
@ -1056,9 +1191,9 @@ void PdfViewPluginBase::HandleViewportMessage(const base::Value& message) {
|
||||
scroll_position_at_last_raster_.y() * zoom_ratio));
|
||||
}
|
||||
|
||||
paint_manager().SetTransform(zoom_ratio, pinch_center,
|
||||
pinch_vector + paint_offset + scroll_delta,
|
||||
true);
|
||||
paint_manager_.SetTransform(zoom_ratio, pinch_center,
|
||||
pinch_vector + paint_offset + scroll_delta,
|
||||
true);
|
||||
needs_reraster_ = false;
|
||||
return;
|
||||
}
|
||||
@ -1069,7 +1204,7 @@ void PdfViewPluginBase::HandleViewportMessage(const base::Value& message) {
|
||||
// that appear after zooming out.
|
||||
// On pinch end the scale is again 1.f and we request a reraster
|
||||
// in the new position.
|
||||
paint_manager().ClearTransform();
|
||||
paint_manager_.ClearTransform();
|
||||
last_bitmap_smaller_ = false;
|
||||
needs_reraster_ = true;
|
||||
|
||||
@ -1370,4 +1505,73 @@ void PdfViewPluginBase::HistogramCustomCounts(const char* name,
|
||||
base::UmaHistogramCustomCounts(name, sample, min, max, bucket_count);
|
||||
}
|
||||
|
||||
void PdfViewPluginBase::DidOpenPreview(std::unique_ptr<UrlLoader> loader,
|
||||
int32_t result) {
|
||||
DCHECK_EQ(result, PP_OK);
|
||||
preview_client_ = std::make_unique<PreviewModeClient>(this);
|
||||
preview_engine_ = std::make_unique<PDFiumEngine>(
|
||||
preview_client_.get(), PDFiumFormFiller::ScriptOption::kNoJavaScript);
|
||||
preview_engine_->HandleDocumentLoad(std::move(loader));
|
||||
}
|
||||
|
||||
void PdfViewPluginBase::OnPrintPreviewLoaded() {
|
||||
// Scroll location is retained across document loads in print preview mode, so
|
||||
// there's no need to override the scroll position by scrolling again.
|
||||
if (IsPreviewingPDF(print_preview_page_count_)) {
|
||||
SendPrintPreviewLoadedNotification();
|
||||
} else {
|
||||
DCHECK_EQ(0, print_preview_loaded_page_count_);
|
||||
print_preview_loaded_page_count_ = 1;
|
||||
AppendBlankPrintPreviewPages();
|
||||
}
|
||||
OnGeometryChanged(0, 0);
|
||||
}
|
||||
|
||||
void PdfViewPluginBase::AppendBlankPrintPreviewPages() {
|
||||
engine()->AppendBlankPages(print_preview_page_count_);
|
||||
LoadNextPreviewPage();
|
||||
}
|
||||
|
||||
void PdfViewPluginBase::ProcessPreviewPageInfo(const std::string& url,
|
||||
int dest_page_index) {
|
||||
DCHECK(IsPrintPreview());
|
||||
DCHECK_GE(dest_page_index, 0);
|
||||
DCHECK_LT(dest_page_index, print_preview_page_count_);
|
||||
|
||||
// Print Preview JS will send the loadPreviewPage message for every page,
|
||||
// including the first page in the print preview, which has already been
|
||||
// loaded when handing the resetPrintPreviewMode message. Just ignore it.
|
||||
if (dest_page_index == 0)
|
||||
return;
|
||||
|
||||
int src_page_index = ExtractPrintPreviewPageIndex(url);
|
||||
DCHECK_GE(src_page_index, 0);
|
||||
|
||||
preview_pages_info_.push(std::make_pair(url, dest_page_index));
|
||||
LoadAvailablePreviewPage();
|
||||
}
|
||||
|
||||
void PdfViewPluginBase::LoadAvailablePreviewPage() {
|
||||
if (preview_pages_info_.empty() ||
|
||||
document_load_state() != DocumentLoadState::kComplete ||
|
||||
preview_document_load_state_ == DocumentLoadState::kLoading) {
|
||||
return;
|
||||
}
|
||||
|
||||
preview_document_load_state_ = DocumentLoadState::kLoading;
|
||||
const std::string& url = preview_pages_info_.front().first;
|
||||
LoadUrl(url, /*is_print_preview=*/true);
|
||||
}
|
||||
|
||||
void PdfViewPluginBase::LoadNextPreviewPage() {
|
||||
if (!preview_pages_info_.empty()) {
|
||||
DCHECK_LT(print_preview_loaded_page_count_, print_preview_page_count_);
|
||||
LoadAvailablePreviewPage();
|
||||
return;
|
||||
}
|
||||
|
||||
if (print_preview_loaded_page_count_ == print_preview_page_count_)
|
||||
SendPrintPreviewLoadedNotification();
|
||||
}
|
||||
|
||||
} // namespace chrome_pdf
|
||||
|
@ -9,14 +9,17 @@
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "base/containers/flat_set.h"
|
||||
#include "base/containers/queue.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "pdf/paint_manager.h"
|
||||
#include "pdf/pdf_engine.h"
|
||||
#include "pdf/pdfium/pdfium_form_filler.h"
|
||||
#include "pdf/preview_mode_client.h"
|
||||
#include "third_party/abseil-cpp/absl/types/optional.h"
|
||||
#include "third_party/blink/public/web/web_print_params.h"
|
||||
#include "third_party/skia/include/core/SkBitmap.h"
|
||||
@ -52,7 +55,8 @@ struct AccessibilityViewportInfo;
|
||||
// Common base to share code between the two plugin implementations,
|
||||
// `OutOfProcessInstance` (Pepper) and `PdfViewWebPlugin` (Blink).
|
||||
class PdfViewPluginBase : public PDFEngine::Client,
|
||||
public PaintManager::Client {
|
||||
public PaintManager::Client,
|
||||
public PreviewModeClient::Client {
|
||||
public:
|
||||
using PDFEngine::Client::ScheduleTaskOnMainThread;
|
||||
|
||||
@ -97,17 +101,22 @@ class PdfViewPluginBase : public PDFEngine::Client,
|
||||
void DocumentHasUnsupportedFeature(const std::string& feature) override;
|
||||
void DocumentLoadProgress(uint32_t available, uint32_t doc_size) override;
|
||||
void FormTextFieldFocusChange(bool in_focus) override;
|
||||
bool IsPrintPreview() override;
|
||||
SkColor GetBackgroundColor() override;
|
||||
void SetIsSelecting(bool is_selecting) override;
|
||||
void SelectionChanged(const gfx::Rect& left, const gfx::Rect& right) override;
|
||||
void EnteredEditMode() override;
|
||||
void DocumentFocusChanged(bool document_has_focus) override;
|
||||
|
||||
// PaintManager::Client
|
||||
// PaintManager::Client:
|
||||
void OnPaint(const std::vector<gfx::Rect>& paint_rects,
|
||||
std::vector<PaintReadyRect>& ready,
|
||||
std::vector<gfx::Rect>& pending) override;
|
||||
|
||||
// PreviewModeClient::Client:
|
||||
void PreviewDocumentLoadComplete() override;
|
||||
void PreviewDocumentLoadFailed() override;
|
||||
|
||||
// Enable accessibility for PDF plugin.
|
||||
void EnableAccessibility();
|
||||
|
||||
@ -153,10 +162,14 @@ class PdfViewPluginBase : public PDFEngine::Client,
|
||||
// their destructor to ensure the engine is destroyed first.
|
||||
void DestroyEngine();
|
||||
|
||||
// Destroys the `PDFiumEngine` used for Print Preview. Subclasses should call
|
||||
// this method in their destructor to ensure the engine is destroyed first.
|
||||
void DestroyPreviewEngine();
|
||||
|
||||
const PDFiumEngine* engine() const { return engine_.get(); }
|
||||
PDFiumEngine* engine() { return engine_.get(); }
|
||||
|
||||
PaintManager& paint_manager() { return paint_manager_; }
|
||||
void ValidateDocumentUrl(base::StringPiece document_url);
|
||||
|
||||
// Starts loading `url`. If `is_print_preview` is `true`, load for print
|
||||
// preview instead of normal PDF viewing.
|
||||
@ -172,10 +185,6 @@ class PdfViewPluginBase : public PDFEngine::Client,
|
||||
// Handles `LoadUrl()` result.
|
||||
virtual void DidOpen(std::unique_ptr<UrlLoader> loader, int32_t result) = 0;
|
||||
|
||||
// Handles `LoadUrl()` result for print preview.
|
||||
virtual void DidOpenPreview(std::unique_ptr<UrlLoader> loader,
|
||||
int32_t result) = 0;
|
||||
|
||||
bool HandleInputEvent(const blink::WebInputEvent& event);
|
||||
|
||||
// Handles `postMessage()` calls from the embedder.
|
||||
@ -284,10 +293,6 @@ class PdfViewPluginBase : public PDFEngine::Client,
|
||||
// Ends the print session. Further calls to `PrintPages()` will fail.
|
||||
void PrintEnd();
|
||||
|
||||
static constexpr bool IsSaveDataSizeValid(size_t size) {
|
||||
return size > 0 && size <= kMaximumSavedFileSize;
|
||||
}
|
||||
|
||||
// Disables browser commands because of restrictions on how the data is to be
|
||||
// used (i.e. can't copy/print). `content_restrictions` should have its bits
|
||||
// set by `chrome_pdf::ContentRestriction` enum values.
|
||||
@ -307,9 +312,6 @@ class PdfViewPluginBase : public PDFEngine::Client,
|
||||
// document.
|
||||
virtual void InvokePrintDialog() = 0;
|
||||
|
||||
// Performs tasks necessary when the document is loaded in print preview mode.
|
||||
virtual void OnPrintPreviewLoaded() = 0;
|
||||
|
||||
// Notifies the embedder of the top-left and bottom-right coordinates of the
|
||||
// current selection.
|
||||
virtual void NotifySelectionChanged(const gfx::PointF& left,
|
||||
@ -371,6 +373,16 @@ class PdfViewPluginBase : public PDFEngine::Client,
|
||||
bool edit_mode() const { return edit_mode_; }
|
||||
void set_edit_mode(bool edit_mode) { edit_mode_ = edit_mode; }
|
||||
|
||||
void set_is_print_preview(bool is_print_preview) {
|
||||
is_print_preview_ = is_print_preview;
|
||||
}
|
||||
|
||||
static bool IsPrintPreviewUrl(base::StringPiece url);
|
||||
|
||||
static constexpr bool IsSaveDataSizeValid(size_t size) {
|
||||
return size > 0 && size <= kMaximumSavedFileSize;
|
||||
}
|
||||
|
||||
private:
|
||||
// Message handlers.
|
||||
void HandleDisplayAnnotationsMessage(const base::Value& message);
|
||||
@ -378,7 +390,9 @@ class PdfViewPluginBase : public PDFEngine::Client,
|
||||
void HandleGetPasswordCompleteMessage(const base::Value& message);
|
||||
void HandleGetSelectedTextMessage(const base::Value& message);
|
||||
void HandleGetThumbnailMessage(const base::Value& message);
|
||||
void HandleLoadPreviewPageMessage(const base::Value& message);
|
||||
void HandlePrintMessage(const base::Value& /*message*/);
|
||||
void HandleResetPrintPreviewModeMessage(const base::Value& message);
|
||||
void HandleRotateClockwiseMessage(const base::Value& /*message*/);
|
||||
void HandleRotateCounterclockwiseMessage(const base::Value& /*message*/);
|
||||
void HandleSaveMessage(const base::Value& message);
|
||||
@ -437,6 +451,28 @@ class PdfViewPluginBase : public PDFEngine::Client,
|
||||
int32_t max,
|
||||
uint32_t bucket_count);
|
||||
|
||||
// Handles `LoadUrl()` result for print preview.
|
||||
void DidOpenPreview(std::unique_ptr<UrlLoader> loader, int32_t result);
|
||||
|
||||
// Performs tasks necessary when the document is loaded in print preview mode.
|
||||
void OnPrintPreviewLoaded();
|
||||
|
||||
// Reduces the document to 1 page and appends `print_preview_page_count_` - 1
|
||||
// blank pages to the document for print preview.
|
||||
void AppendBlankPrintPreviewPages();
|
||||
|
||||
// Process the preview page data information. `src_url` specifies the preview
|
||||
// page data location. The `src_url` is in the format:
|
||||
// chrome://print/id/page_number/print.pdf
|
||||
// `dest_page_index` specifies the blank page index that needs to be replaced
|
||||
// with the new page data.
|
||||
void ProcessPreviewPageInfo(const std::string& src_url, int dest_page_index);
|
||||
// Load the next available preview page into the blank page.
|
||||
void LoadAvailablePreviewPage();
|
||||
|
||||
// Called after a preview page has loaded or failed to load.
|
||||
void LoadNextPreviewPage();
|
||||
|
||||
std::unique_ptr<PDFiumEngine> engine_;
|
||||
PaintManager paint_manager_{this};
|
||||
|
||||
@ -543,6 +579,37 @@ class PdfViewPluginBase : public PDFEngine::Client,
|
||||
|
||||
// For identifying actual print operations to avoid double logging of UMA.
|
||||
bool print_pages_called_;
|
||||
|
||||
// The PreviewModeClient used for print preview. Will be passed to
|
||||
// `preview_engine_`.
|
||||
std::unique_ptr<PreviewModeClient> preview_client_;
|
||||
|
||||
// This engine is used to render the individual preview page data. This is
|
||||
// used only in print preview mode. This will use `PreviewModeClient`
|
||||
// interface which has very limited access to the pp::Instance.
|
||||
std::unique_ptr<PDFiumEngine> preview_engine_;
|
||||
|
||||
DocumentLoadState preview_document_load_state_ = DocumentLoadState::kComplete;
|
||||
|
||||
// True if the plugin is loaded in print preview, otherwise false.
|
||||
bool is_print_preview_ = false;
|
||||
|
||||
// Number of pages in print preview mode for non-PDF source, 0 if print
|
||||
// previewing a PDF, and -1 if not in print preview mode.
|
||||
int print_preview_page_count_ = -1;
|
||||
|
||||
// Number of pages loaded in print preview mode for non-PDF source. Always
|
||||
// less than or equal to `print_preview_page_count_`.
|
||||
int print_preview_loaded_page_count_ = -1;
|
||||
|
||||
// Used to manage loaded print preview page information. A `PreviewPageInfo`
|
||||
// consists of data source URL string and the page index in the destination
|
||||
// document.
|
||||
// The URL string embeds a page number that can be found with
|
||||
// ExtractPrintPreviewPageIndex(). This page number is always greater than 0.
|
||||
// The page index is always in the range of [0, print_preview_page_count_).
|
||||
using PreviewPageInfo = std::pair<std::string, int>;
|
||||
base::queue<PreviewPageInfo> preview_pages_info_;
|
||||
};
|
||||
|
||||
} // namespace chrome_pdf
|
||||
|
@ -116,11 +116,6 @@ class FakePdfViewPluginBase : public PdfViewPluginBase {
|
||||
|
||||
MOCK_METHOD(void, DidOpen, (std::unique_ptr<UrlLoader>, int32_t), (override));
|
||||
|
||||
MOCK_METHOD(void,
|
||||
DidOpenPreview,
|
||||
(std::unique_ptr<UrlLoader>, int32_t),
|
||||
(override));
|
||||
|
||||
void SendMessage(base::Value message) override {
|
||||
sent_message_ = std::move(message);
|
||||
}
|
||||
@ -157,8 +152,6 @@ class FakePdfViewPluginBase : public PdfViewPluginBase {
|
||||
|
||||
MOCK_METHOD(void, DidStopLoading, (), (override));
|
||||
|
||||
MOCK_METHOD(void, OnPrintPreviewLoaded, (), (override));
|
||||
|
||||
MOCK_METHOD(void, InvokePrintDialog, (), (override));
|
||||
|
||||
MOCK_METHOD(void,
|
||||
|
@ -167,7 +167,10 @@ class BlinkContainerWrapper final : public PdfViewWebPlugin::ContainerWrapper {
|
||||
}
|
||||
|
||||
void UpdateTextInputState() override {
|
||||
return GetFrame()->FrameWidget()->UpdateTextInputState();
|
||||
// `widget` is null in Print Preview.
|
||||
auto* widget = GetFrame()->FrameWidget();
|
||||
if (widget)
|
||||
widget->UpdateTextInputState();
|
||||
}
|
||||
|
||||
blink::WebLocalFrame* GetFrame() override {
|
||||
@ -207,6 +210,22 @@ bool PdfViewWebPlugin::InitializeCommon(
|
||||
std::unique_ptr<ContainerWrapper> container_wrapper) {
|
||||
container_wrapper_ = std::move(container_wrapper);
|
||||
|
||||
// Check if the PDF is being loaded in the PDF chrome extension. We only allow
|
||||
// the plugin to be loaded in the extension and print preview to avoid
|
||||
// exposing sensitive APIs directly to external websites.
|
||||
std::string document_url;
|
||||
auto* container = Container();
|
||||
if (container) {
|
||||
GURL maybe_url(container->GetDocument().Url());
|
||||
if (maybe_url.is_valid())
|
||||
document_url = maybe_url.possibly_invalid_spec();
|
||||
}
|
||||
|
||||
base::StringPiece document_url_piece(document_url);
|
||||
set_is_print_preview(IsPrintPreviewUrl(document_url_piece));
|
||||
// TODO(crbug.com/1123621): Consider calling ValidateDocumentUrl() or
|
||||
// something like it once the process model has been finalized.
|
||||
|
||||
absl::optional<ParsedParams> params = ParseWebPluginParams(initial_params_);
|
||||
|
||||
// The contents of `initial_params_` are no longer needed.
|
||||
@ -232,6 +251,7 @@ void PdfViewWebPlugin::Destroy() {
|
||||
if (container_wrapper_) {
|
||||
// Explicitly destroy the PDFEngine during destruction as it may call back
|
||||
// into this object.
|
||||
DestroyPreviewEngine();
|
||||
DestroyEngine();
|
||||
PerProcessInitializer::GetInstance().Release();
|
||||
container_wrapper_.reset();
|
||||
@ -501,10 +521,6 @@ pp::Instance* PdfViewWebPlugin::GetPluginInstance() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool PdfViewWebPlugin::IsPrintPreview() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void PdfViewWebPlugin::SetSelectedText(const std::string& selected_text) {
|
||||
selected_text_ = blink::WebString::FromUTF8(selected_text);
|
||||
container_wrapper_->TextSelectionChanged(
|
||||
@ -605,11 +621,6 @@ void PdfViewWebPlugin::DidOpen(std::unique_ptr<UrlLoader> loader,
|
||||
}
|
||||
}
|
||||
|
||||
void PdfViewWebPlugin::DidOpenPreview(std::unique_ptr<UrlLoader> loader,
|
||||
int32_t result) {
|
||||
NOTIMPLEMENTED();
|
||||
}
|
||||
|
||||
void PdfViewWebPlugin::SendMessage(base::Value message) {
|
||||
post_message_sender_.Post(std::move(message));
|
||||
}
|
||||
@ -681,10 +692,6 @@ void PdfViewWebPlugin::DidStopLoading() {
|
||||
NOTIMPLEMENTED();
|
||||
}
|
||||
|
||||
void PdfViewWebPlugin::OnPrintPreviewLoaded() {
|
||||
NOTIMPLEMENTED();
|
||||
}
|
||||
|
||||
void PdfViewWebPlugin::InvokePrintDialog() {
|
||||
ScheduleTaskOnMainThread(
|
||||
FROM_HERE,
|
||||
|
@ -170,7 +170,6 @@ class PdfViewWebPlugin final : public PdfViewPluginBase,
|
||||
const char16_t* term,
|
||||
bool case_sensitive) override;
|
||||
pp::Instance* GetPluginInstance() override;
|
||||
bool IsPrintPreview() override;
|
||||
void SetSelectedText(const std::string& selected_text) override;
|
||||
void SetLinkUnderCursor(const std::string& link_under_cursor) override;
|
||||
bool IsValidLink(const std::string& url) override;
|
||||
@ -207,8 +206,6 @@ class PdfViewWebPlugin final : public PdfViewPluginBase,
|
||||
base::WeakPtr<PdfViewPluginBase> GetWeakPtr() override;
|
||||
std::unique_ptr<UrlLoader> CreateUrlLoaderInternal() override;
|
||||
void DidOpen(std::unique_ptr<UrlLoader> loader, int32_t result) override;
|
||||
void DidOpenPreview(std::unique_ptr<UrlLoader> loader,
|
||||
int32_t result) override;
|
||||
void SendMessage(base::Value message) override;
|
||||
void SaveAs() override;
|
||||
void InitImageData(const gfx::Size& size) override;
|
||||
@ -224,7 +221,6 @@ class PdfViewWebPlugin final : public PdfViewPluginBase,
|
||||
void SetPluginCanSave(bool can_save) override;
|
||||
void DidStartLoading() override;
|
||||
void DidStopLoading() override;
|
||||
void OnPrintPreviewLoaded() override;
|
||||
void InvokePrintDialog() override;
|
||||
void NotifySelectionChanged(const gfx::PointF& left,
|
||||
int left_height,
|
||||
|
Reference in New Issue
Block a user