forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpdf_view_web_plugin.h
516 lines (409 loc) · 19.4 KB
/
pdf_view_web_plugin.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
// Copyright 2020 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_PDF_VIEW_WEB_PLUGIN_H_
#define PDF_PDF_VIEW_WEB_PLUGIN_H_
#include <stdint.h>
#include <memory>
#include <string>
#include <vector>
#include "base/containers/flat_set.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/values.h"
#include "cc/paint/paint_image.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "pdf/mojom/pdf.mojom.h"
#include "pdf/pdf_accessibility_action_handler.h"
#include "pdf/pdf_engine.h"
#include "pdf/pdf_view_plugin_base.h"
#include "pdf/pdfium/pdfium_form_filler.h"
#include "pdf/post_message_receiver.h"
#include "pdf/ppapi_migration/url_loader.h"
#include "pdf/v8_value_converter.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/web/web_plugin.h"
#include "third_party/blink/public/web/web_plugin_container.h"
#include "third_party/blink/public/web/web_plugin_params.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/geometry/vector2d_f.h"
#include "v8/include/v8.h"
namespace blink {
class WebAssociatedURLLoader;
class WebURL;
class WebURLRequest;
struct WebAssociatedURLLoaderOptions;
} // namespace blink
namespace gfx {
class PointF;
class Range;
class Rect;
} // namespace gfx
namespace net {
class SiteForCookies;
} // namespace net
namespace printing {
class MetafileSkia;
} // namespace printing
namespace chrome_pdf {
class MetricsHandler;
class PDFiumEngine;
class PdfAccessibilityDataHandler;
class PdfViewWebPlugin final : public PdfViewPluginBase,
public blink::WebPlugin,
public pdf::mojom::PdfListener,
public BlinkUrlLoader::Client,
public PostMessageReceiver::Client,
public PdfAccessibilityActionHandler {
public:
// Must match `SaveRequestType` in chrome/browser/resources/pdf/constants.ts.
enum class SaveRequestType {
kAnnotation = 0,
kOriginal = 1,
kEdited = 2,
};
// Provides services from the plugin's container.
class Client : public V8ValueConverter {
public:
virtual ~Client() = default;
virtual base::WeakPtr<Client> GetWeakPtr() = 0;
// Creates a new `PDFiumEngine`.
virtual std::unique_ptr<PDFiumEngine> CreateEngine(
PDFEngine::Client* client,
PDFiumFormFiller::ScriptOption script_option);
// Passes the plugin container to the client. This is first called in
// `Initialize()`, and cleared to null in `Destroy()`. The container may
// also be null for testing.
virtual void SetPluginContainer(blink::WebPluginContainer* container) = 0;
// Returns the plugin container set by `SetPluginContainer()`.
virtual blink::WebPluginContainer* PluginContainer() = 0;
// Returrns the document's site for cookies.
virtual net::SiteForCookies SiteForCookies() const = 0;
// Resolves `partial_url` relative to the document's base URL.
virtual blink::WebURL CompleteURL(
const blink::WebString& partial_url) const = 0;
// Enqueues a "message" event carrying `message` to the plugin embedder.
virtual void PostMessage(base::Value::Dict message) {}
// Invalidates the entire web plugin container and schedules a paint of the
// page in it.
virtual void Invalidate() = 0;
// Notifies the container about which touch events the plugin accepts.
virtual void RequestTouchEventType(
blink::WebPluginContainer::TouchEventRequestType request_type) = 0;
// Notify the web plugin container about the total matches of a find
// request.
virtual void ReportFindInPageMatchCount(int identifier,
int total,
bool final_update) = 0;
// Notify the web plugin container about the selected find result in plugin.
virtual void ReportFindInPageSelection(int identifier, int index) = 0;
// Notify the web plugin container about find result tickmarks.
virtual void ReportFindInPageTickmarks(
const std::vector<gfx::Rect>& tickmarks) = 0;
// Returns the device scale factor.
virtual float DeviceScaleFactor() = 0;
// Gets the scroll position.
virtual gfx::PointF GetScrollPosition() = 0;
// Tells the embedder to allow the plugin to handle find requests.
virtual void UsePluginAsFindHandler() = 0;
// Calls underlying WebLocalFrame::SetReferrerForRequest().
virtual void SetReferrerForRequest(blink::WebURLRequest& request,
const blink::WebURL& referrer_url) = 0;
// Calls underlying WebLocalFrame::Alert().
virtual void Alert(const blink::WebString& message) = 0;
// Calls underlying WebLocalFrame::Confirm().
virtual bool Confirm(const blink::WebString& message) = 0;
// Calls underlying WebLocalFrame::Prompt().
virtual blink::WebString Prompt(const blink::WebString& message,
const blink::WebString& default_value) = 0;
// Calls underlying WebLocalFrame::TextSelectionChanged().
virtual void TextSelectionChanged(const blink::WebString& selection_text,
uint32_t offset,
const gfx::Range& range) = 0;
// Calls underlying WebLocalFrame::CreateAssociatedURLLoader().
virtual std::unique_ptr<blink::WebAssociatedURLLoader>
CreateAssociatedURLLoader(
const blink::WebAssociatedURLLoaderOptions& options) = 0;
// Notifies the frame widget about the text input type change.
virtual void UpdateTextInputState() = 0;
// Notifies the frame widget about the selection bound change.
virtual void UpdateSelectionBounds() = 0;
// Gets the embedder's origin as a serialized string.
virtual std::string GetEmbedderOriginString() = 0;
// Returns whether the plugin container's frame exists.
virtual bool HasFrame() const = 0;
// Notifies the frame's client that the plugin started loading.
virtual void DidStartLoading() = 0;
// Notifies the frame's client that the plugin stopped loading.
virtual void DidStopLoading() = 0;
// Prints the plugin element.
virtual void Print() {}
// Sends over a string to be recorded by user metrics as a computed action.
// When you use this, you need to also update the rules for extracting known
// actions in tools/metrics/actions/extract_actions.py.
virtual void RecordComputedAction(const std::string& action) {}
// Creates an implementation of `PdfAccessibilityDataHandler` catered to the
// client.
virtual std::unique_ptr<PdfAccessibilityDataHandler>
CreateAccessibilityDataHandler(
PdfAccessibilityActionHandler* action_handler);
};
PdfViewWebPlugin(std::unique_ptr<Client> client,
mojo::AssociatedRemote<pdf::mojom::PdfService> pdf_service,
const blink::WebPluginParams& params);
PdfViewWebPlugin(const PdfViewWebPlugin& other) = delete;
PdfViewWebPlugin& operator=(const PdfViewWebPlugin& other) = delete;
// blink::WebPlugin:
bool Initialize(blink::WebPluginContainer* container) override;
void Destroy() override;
blink::WebPluginContainer* Container() const override;
v8::Local<v8::Object> V8ScriptableObject(v8::Isolate* isolate) override;
bool SupportsKeyboardFocus() const override;
void UpdateAllLifecyclePhases(blink::DocumentUpdateReason reason) override;
void Paint(cc::PaintCanvas* canvas, const gfx::Rect& rect) override;
void UpdateGeometry(const gfx::Rect& window_rect,
const gfx::Rect& clip_rect,
const gfx::Rect& unobscured_rect,
bool is_visible) override;
void UpdateFocus(bool focused, blink::mojom::FocusType focus_type) override;
void UpdateVisibility(bool visibility) override;
blink::WebInputEventResult HandleInputEvent(
const blink::WebCoalescedInputEvent& event,
ui::Cursor* cursor) override;
void DidReceiveResponse(const blink::WebURLResponse& response) override;
void DidReceiveData(const char* data, size_t data_length) override;
void DidFinishLoading() override;
void DidFailLoading(const blink::WebURLError& error) override;
bool SupportsPaginatedPrint() override;
bool GetPrintPresetOptionsFromDocument(
blink::WebPrintPresetOptions* print_preset_options) override;
int PrintBegin(const blink::WebPrintParams& print_params) override;
void PrintPage(int page_number, cc::PaintCanvas* canvas) override;
void PrintEnd() override;
bool HasSelection() const override;
blink::WebString SelectionAsText() const override;
blink::WebString SelectionAsMarkup() const override;
bool CanEditText() const override;
bool HasEditableText() const override;
bool CanUndo() const override;
bool CanRedo() const override;
bool ExecuteEditCommand(const blink::WebString& name,
const blink::WebString& value) override;
blink::WebURL LinkAtPosition(const gfx::Point& /*position*/) const override;
bool StartFind(const blink::WebString& search_text,
bool case_sensitive,
int identifier) override;
void SelectFindResult(bool forward, int identifier) override;
void StopFind() override;
bool CanRotateView() override;
void RotateView(blink::WebPlugin::RotationType type) override;
bool ShouldDispatchImeEventsToPlugin() override;
blink::WebTextInputType GetPluginTextInputType() override;
gfx::Rect GetPluginCaretBounds() override;
void ImeSetCompositionForPlugin(
const blink::WebString& text,
const std::vector<ui::ImeTextSpan>& ime_text_spans,
const gfx::Range& replacement_range,
int selection_start,
int selection_end) override;
void ImeCommitTextForPlugin(
const blink::WebString& text,
const std::vector<ui::ImeTextSpan>& ime_text_spans,
const gfx::Range& replacement_range,
int relative_cursor_pos) override;
void ImeFinishComposingTextForPlugin(bool keep_selection) override;
// PDFEngine::Client:
void UpdateCursor(ui::mojom::CursorType new_cursor_type) override;
void UpdateTickMarks(const std::vector<gfx::Rect>& tickmarks) override;
void NotifyNumberOfFindResultsChanged(int total, bool final_result) override;
void NotifySelectedFindResultChanged(int current_find_index) override;
void Alert(const std::string& message) override;
bool Confirm(const std::string& message) override;
std::string Prompt(const std::string& question,
const std::string& default_answer) override;
void SubmitForm(const std::string& url,
const void* data,
int length) override;
std::unique_ptr<UrlLoader> CreateUrlLoader() override;
std::vector<SearchStringResult> SearchString(const char16_t* string,
const char16_t* term,
bool case_sensitive) override;
void DocumentHasUnsupportedFeature(const std::string& feature) override;
bool IsPrintPreview() const override;
SkColor GetBackgroundColor() const override;
void CaretChanged(const gfx::Rect& caret_rect) override;
void EnteredEditMode() override;
void SetSelectedText(const std::string& selected_text) override;
bool IsValidLink(const std::string& url) override;
// pdf::mojom::PdfListener:
void SetCaretPosition(const gfx::PointF& position) override;
void MoveRangeSelectionExtent(const gfx::PointF& extent) override;
void SetSelectionBounds(const gfx::PointF& base,
const gfx::PointF& extent) override;
// BlinkUrlLoader::Client:
bool IsValid() const override;
blink::WebURL CompleteURL(const blink::WebString& partial_url) const override;
net::SiteForCookies SiteForCookies() const override;
void SetReferrerForRequest(blink::WebURLRequest& request,
const blink::WebURL& referrer_url) override;
std::unique_ptr<blink::WebAssociatedURLLoader> CreateAssociatedURLLoader(
const blink::WebAssociatedURLLoaderOptions& options) override;
// PostMessageReceiver::Client:
void OnMessage(const base::Value::Dict& message) override;
// PaintManager::Client:
void InvalidatePluginContainer() override;
void UpdateSnapshot(sk_sp<SkImage> snapshot) override;
void UpdateScale(float scale) override;
void UpdateLayerTransform(float scale,
const gfx::Vector2dF& translate) override;
// PdfAccessibilityActionHandler:
void EnableAccessibility() override;
void HandleAccessibilityAction(
const AccessibilityActionData& action_data) override;
// Initializes the plugin for testing, bypassing certain consistency checks.
bool InitializeForTesting();
const gfx::Rect& GetPluginRectForTesting() const { return plugin_rect(); }
float GetDeviceScaleForTesting() const { return device_scale(); }
protected:
// PdfViewPluginBase:
std::unique_ptr<PDFiumEngine> CreateEngine(
PDFEngine::Client* client,
PDFiumFormFiller::ScriptOption script_option) override;
void LoadUrl(base::StringPiece url, LoadUrlCallback callback) override;
base::WeakPtr<PdfViewPluginBase> GetWeakPtr() override;
void OnDocumentLoadComplete() override;
void SendMessage(base::Value::Dict message) override;
void SetFormTextFieldInFocus(bool in_focus) override;
void SetAccessibilityDocInfo(AccessibilityDocInfo doc_info) override;
void SetAccessibilityPageInfo(AccessibilityPageInfo page_info,
std::vector<AccessibilityTextRunInfo> text_runs,
std::vector<AccessibilityCharInfo> chars,
AccessibilityPageObjects page_objects) override;
void SetAccessibilityViewportInfo(
AccessibilityViewportInfo viewport_info) override;
void SetContentRestrictions(int content_restrictions) override;
void DidStartLoading() override;
void DidStopLoading() override;
void InvokePrintDialog() override;
void NotifySelectionChanged(const gfx::PointF& left,
int left_height,
const gfx::PointF& right,
int right_height) override;
void UserMetricsRecordAction(const std::string& action) override;
bool full_frame() const override;
gfx::Vector2d plugin_offset_in_frame() const override;
private:
// Call `Destroy()` instead.
~PdfViewWebPlugin() override;
bool InitializeCommon();
// Sends whether to do smooth scrolling.
void SendSetSmoothScrolling();
// Handles `Open()` result for `form_loader_`.
void DidFormOpen(int32_t result);
// Creates a URL loader with universal access.
std::unique_ptr<UrlLoader> CreateUrlLoaderInternal();
// Handles message for saving the PDF.
void HandleSaveMessage(const base::Value::Dict& message);
void SaveToBuffer(const std::string& token);
void SaveToFile(const std::string& token);
// Handles message for setting the background color.
void HandleSetBackgroundColorMessage(const base::Value::Dict& message);
// Recalculates values that depend on scale factors.
void UpdateScaledValues();
void OnViewportChanged(const gfx::Rect& plugin_rect_in_css_pixel,
float new_device_scale);
// Text editing methods.
bool SelectAll();
bool Cut();
bool Paste(const blink::WebString& value);
bool Undo();
bool Redo();
// Helper method for converting IME text to input events.
// TODO(crbug.com/1253665): Consider handling composition events.
void HandleImeCommit(const blink::WebString& text);
// Callback to print without re-entrancy issues. The callback prevents the
// invocation of printing in the middle of an event handler, which is risky;
// see crbug.com/66334.
// TODO(crbug.com/1217012): Re-evaluate the need for a callback when parts of
// the plugin are moved off the main thread.
void OnInvokePrintDialog();
void ResetRecentlySentFindUpdate();
// Records metrics about the document metadata.
void RecordDocumentMetrics();
// Sends the attachments data.
void SendAttachments();
// Sends the bookmarks data.
void SendBookmarks();
// Send document metadata data.
void SendMetadata();
blink::WebString selected_text_;
std::unique_ptr<Client> const client_;
// Used to access the services provided by the browser.
mojo::AssociatedRemote<pdf::mojom::PdfService> const pdf_service_;
mojo::Receiver<pdf::mojom::PdfListener> listener_receiver_{this};
// The id of the current find operation, or -1 if no current operation is
// present.
int find_identifier_ = -1;
blink::WebTextInputType text_input_type_ =
blink::WebTextInputType::kWebTextInputTypeNone;
gfx::Rect caret_rect_;
blink::WebString composition_text_;
// Whether the plugin element currently has focus.
bool has_focus_ = false;
blink::WebPluginParams initial_params_;
v8::Persistent<v8::Object> scriptable_receiver_;
// The current image snapshot.
cc::PaintImage snapshot_;
// Translate from snapshot to device pixels.
gfx::Vector2dF snapshot_translate_;
// Scale from snapshot to device pixels.
float snapshot_scale_ = 1.0f;
// The viewport coordinates to DIP (device-independent pixel) ratio.
float viewport_to_dip_scale_ = 1.0f;
// The device pixel to CSS pixel ratio.
float device_to_css_scale_ = 1.0f;
// Combined translate from snapshot to device to CSS pixels.
gfx::Vector2dF total_translate_;
// The plugin rect in CSS pixels.
gfx::Rect css_plugin_rect_;
// True if the plugin occupies the entire frame (not embedded).
bool full_frame_ = false;
// The background color of the PDF viewer.
SkColor background_color_ = SK_ColorTRANSPARENT;
// If true, the render frame has been notified that we're starting a network
// request so that it can start the throbber. It will be notified again once
// the document finishes loading.
bool did_call_start_loading_ = false;
// Used for submitting forms.
std::unique_ptr<UrlLoader> form_loader_;
// Handler for accessibility data updates.
std::unique_ptr<PdfAccessibilityDataHandler> const
pdf_accessibility_data_handler_;
// Whether an update to the number of find results found was sent less than
// `kFindResultCooldown` TimeDelta ago.
bool recently_sent_find_update_ = false;
// Stores the tickmarks to be shown for the current find results.
std::vector<gfx::Rect> tickmarks_;
// Whether the document is in edit mode.
bool edit_mode_ = false;
// Only instantiated when not print previewing.
std::unique_ptr<MetricsHandler> metrics_handler_;
// Keeps track of which unsupported features have been reported to avoid
// spamming the metrics if a feature shows up many times per document.
base::flat_set<std::string> unsupported_features_reported_;
// Indicates whether the browser has been notified about an unsupported
// feature once, which helps prevent the infobar from going up more than once.
bool notified_browser_about_unsupported_feature_ = false;
// The metafile in which to save the printed output. Assigned a value only
// between `PrintBegin()` and `PrintEnd()` calls.
raw_ptr<printing::MetafileSkia> printing_metafile_ = nullptr;
// The indices of pages to print.
std::vector<int> pages_to_print_;
// Whether the plugin is loaded in Print Preview.
bool is_print_preview_ = false;
base::WeakPtrFactory<PdfViewWebPlugin> weak_factory_{this};
};
} // namespace chrome_pdf
#endif // PDF_PDF_VIEW_WEB_PLUGIN_H_