1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "pdf/pdf_view_web_plugin.h"
14 #include "base/check_op.h"
15 #include "base/notreached.h"
16 #include "base/thread_annotations.h"
17 #include "base/threading/thread_checker.h"
18 #include "cc/paint/paint_canvas.h"
19 #include "net/cookies/site_for_cookies.h"
20 #include "pdf/pdf_engine.h"
21 #include "pdf/pdf_init.h"
22 #include "pdf/pdfium/pdfium_engine.h"
23 #include "pdf/ppapi_migration/url_loader.h"
24 #include "ppapi/c/pp_errors.h"
25 #include "third_party/blink/public/common/input/web_coalesced_input_event.h"
26 #include "third_party/blink/public/common/metrics/document_update_reason.h"
27 #include "third_party/blink/public/mojom/input/focus_type.mojom-shared.h"
28 #include "third_party/blink/public/platform/web_input_event_result.h"
29 #include "third_party/blink/public/platform/web_rect.h"
30 #include "third_party/blink/public/platform/web_string.h"
31 #include "third_party/blink/public/platform/web_url.h"
32 #include "third_party/blink/public/platform/web_url_error.h"
33 #include "third_party/blink/public/platform/web_url_request.h"
34 #include "third_party/blink/public/platform/web_url_response.h"
35 #include "third_party/blink/public/web/web_associated_url_loader.h"
36 #include "third_party/blink/public/web/web_associated_url_loader_options.h"
37 #include "third_party/blink/public/web/web_document.h"
38 #include "third_party/blink/public/web/web_local_frame.h"
39 #include "third_party/blink/public/web/web_plugin_container.h"
40 #include "third_party/blink/public/web/web_plugin_params.h"
41 #include "ui/base/cursor/cursor.h"
43 namespace chrome_pdf {
47 // Initialization performed per renderer process. Initialization may be
48 // triggered from multiple plugin instances, but should only execute once.
50 // TODO(crbug.com/1123621): We may be able to simplify this once we've figured
51 // out exactly which processes need to initialize and shutdown PDFium.
52 class PerProcessInitializer final {
54 static PerProcessInitializer& GetInstance() {
55 static PerProcessInitializer instance;
60 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
62 DCHECK_GE(init_count_, 0);
63 if (init_count_++ > 0)
66 DCHECK(!IsSDKInitializedViaPlugin());
67 // TODO(crbug.com/1111024): Support JavaScript.
68 InitializeSDK(/*enable_v8=*/false);
69 SetIsSDKInitializedViaPlugin(true);
73 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
75 DCHECK_GT(init_count_, 0);
76 if (--init_count_ > 0)
79 DCHECK(IsSDKInitializedViaPlugin());
81 SetIsSDKInitializedViaPlugin(false);
85 int init_count_ GUARDED_BY_CONTEXT(thread_checker_) = 0;
87 // TODO(crbug.com/1123731): Assuming PDFium is thread-hostile for now, and
88 // must use one thread exclusively.
89 THREAD_CHECKER(thread_checker_);
94 PdfViewWebPlugin::PdfViewWebPlugin(const blink::WebPluginParams& params)
95 : initial_params_(params) {}
97 PdfViewWebPlugin::~PdfViewWebPlugin() = default;
99 // Modeled on `OutOfProcessInstance::Init()`.
100 bool PdfViewWebPlugin::Initialize(blink::WebPluginContainer* container) {
101 DCHECK_EQ(container->Plugin(), this);
102 container_ = container;
104 std::string stream_url;
105 for (size_t i = 0; i < initial_params_.attribute_names.size(); ++i) {
106 if (initial_params_.attribute_names[i] == "stream-url")
107 stream_url = initial_params_.attribute_values[i].Utf8();
110 // Contents of `initial_params_` no longer needed.
111 initial_params_ = {};
113 PerProcessInitializer::GetInstance().Acquire();
114 InitializeEngine(PDFiumFormFiller::ScriptOption::kNoJavaScript);
115 LoadUrl(stream_url, /*is_print_preview=*/false);
119 void PdfViewWebPlugin::Destroy() {
121 // Explicitly destroy the PDFEngine during destruction as it may call back
124 PerProcessInitializer::GetInstance().Release();
127 container_ = nullptr;
131 blink::WebPluginContainer* PdfViewWebPlugin::Container() const {
135 void PdfViewWebPlugin::UpdateAllLifecyclePhases(
136 blink::DocumentUpdateReason reason) {}
138 void PdfViewWebPlugin::Paint(cc::PaintCanvas* canvas,
139 const blink::WebRect& rect) {}
141 void PdfViewWebPlugin::UpdateGeometry(const blink::WebRect& window_rect,
142 const blink::WebRect& clip_rect,
143 const blink::WebRect& unobscured_rect,
146 void PdfViewWebPlugin::UpdateFocus(bool focused,
147 blink::mojom::FocusType focus_type) {}
149 void PdfViewWebPlugin::UpdateVisibility(bool visibility) {}
151 blink::WebInputEventResult PdfViewWebPlugin::HandleInputEvent(
152 const blink::WebCoalescedInputEvent& event,
153 ui::Cursor* cursor) {
154 return blink::WebInputEventResult::kNotHandled;
157 void PdfViewWebPlugin::DidReceiveResponse(
158 const blink::WebURLResponse& response) {}
160 void PdfViewWebPlugin::DidReceiveData(const char* data, size_t data_length) {}
162 void PdfViewWebPlugin::DidFinishLoading() {}
164 void PdfViewWebPlugin::DidFailLoading(const blink::WebURLError& error) {}
166 void PdfViewWebPlugin::ProposeDocumentLayout(const DocumentLayout& layout) {}
168 void PdfViewWebPlugin::Invalidate(const gfx::Rect& rect) {}
170 void PdfViewWebPlugin::DidScroll(const gfx::Vector2d& offset) {}
172 void PdfViewWebPlugin::ScrollToX(int x_in_screen_coords) {}
174 void PdfViewWebPlugin::ScrollToY(int y_in_screen_coords,
175 bool compensate_for_toolbar) {}
177 void PdfViewWebPlugin::ScrollBy(const gfx::Vector2d& scroll_delta) {}
179 void PdfViewWebPlugin::ScrollToPage(int page) {}
181 void PdfViewWebPlugin::NavigateTo(const std::string& url,
182 WindowOpenDisposition disposition) {}
184 void PdfViewWebPlugin::NavigateToDestination(int page,
187 const float* zoom) {}
189 void PdfViewWebPlugin::UpdateCursor(PP_CursorType_Dev cursor) {}
191 void PdfViewWebPlugin::UpdateTickMarks(
192 const std::vector<gfx::Rect>& tickmarks) {}
194 void PdfViewWebPlugin::NotifyNumberOfFindResultsChanged(int total,
195 bool final_result) {}
197 void PdfViewWebPlugin::NotifySelectedFindResultChanged(int current_find_index) {
200 void PdfViewWebPlugin::NotifyTouchSelectionOccurred() {}
202 void PdfViewWebPlugin::GetDocumentPassword(
203 base::OnceCallback<void(const std::string&)> callback) {}
205 void PdfViewWebPlugin::Beep() {}
207 void PdfViewWebPlugin::Alert(const std::string& message) {}
209 bool PdfViewWebPlugin::Confirm(const std::string& message) {
213 std::string PdfViewWebPlugin::Prompt(const std::string& question,
214 const std::string& default_answer) {
218 std::string PdfViewWebPlugin::GetURL() {
222 void PdfViewWebPlugin::Email(const std::string& to,
223 const std::string& cc,
224 const std::string& bcc,
225 const std::string& subject,
226 const std::string& body) {}
228 void PdfViewWebPlugin::Print() {}
230 void PdfViewWebPlugin::SubmitForm(const std::string& url,
234 std::unique_ptr<UrlLoader> PdfViewWebPlugin::CreateUrlLoader() {
238 std::vector<PDFEngine::Client::SearchStringResult>
239 PdfViewWebPlugin::SearchString(const base::char16* string,
240 const base::char16* term,
241 bool case_sensitive) {
245 void PdfViewWebPlugin::DocumentLoadComplete(
246 const PDFEngine::DocumentFeatures& document_features) {
250 void PdfViewWebPlugin::DocumentLoadFailed() {
254 pp::Instance* PdfViewWebPlugin::GetPluginInstance() {
258 void PdfViewWebPlugin::DocumentHasUnsupportedFeature(
259 const std::string& feature) {}
261 void PdfViewWebPlugin::DocumentLoadProgress(uint32_t available,
262 uint32_t doc_size) {}
264 void PdfViewWebPlugin::FormTextFieldFocusChange(bool in_focus) {}
266 bool PdfViewWebPlugin::IsPrintPreview() {
270 uint32_t PdfViewWebPlugin::GetBackgroundColor() {
274 void PdfViewWebPlugin::IsSelectingChanged(bool is_selecting) {}
276 void PdfViewWebPlugin::SelectionChanged(const gfx::Rect& left,
277 const gfx::Rect& right) {}
279 void PdfViewWebPlugin::EnteredEditMode() {}
281 float PdfViewWebPlugin::GetToolbarHeightInScreenCoords() {
285 void PdfViewWebPlugin::DocumentFocusChanged(bool document_has_focus) {}
287 void PdfViewWebPlugin::SetSelectedText(const std::string& selected_text) {
291 void PdfViewWebPlugin::SetLinkUnderCursor(
292 const std::string& link_under_cursor) {
296 bool PdfViewWebPlugin::IsValidLink(const std::string& url) {
297 return base::Value(url).is_string();
300 bool PdfViewWebPlugin::IsValid() const {
301 return container_ && container_->GetDocument().GetFrame();
304 blink::WebURL PdfViewWebPlugin::CompleteURL(
305 const blink::WebString& partial_url) const {
307 return container_->GetDocument().CompleteURL(partial_url);
310 net::SiteForCookies PdfViewWebPlugin::SiteForCookies() const {
312 return container_->GetDocument().SiteForCookies();
315 void PdfViewWebPlugin::SetReferrerForRequest(
316 blink::WebURLRequest& request,
317 const blink::WebURL& referrer_url) {
319 container_->GetDocument().GetFrame()->SetReferrerForRequest(request,
323 std::unique_ptr<blink::WebAssociatedURLLoader>
324 PdfViewWebPlugin::CreateAssociatedURLLoader(
325 const blink::WebAssociatedURLLoaderOptions& options) {
327 return container_->GetDocument().GetFrame()->CreateAssociatedURLLoader(
331 base::WeakPtr<PdfViewPluginBase> PdfViewWebPlugin::GetWeakPtr() {
332 return weak_factory_.GetWeakPtr();
335 std::unique_ptr<UrlLoader> PdfViewWebPlugin::CreateUrlLoaderInternal() {
336 auto loader = std::make_unique<BlinkUrlLoader>(weak_factory_.GetWeakPtr());
337 loader->GrantUniversalAccess();
341 // Modeled on `OutOfProcessInstance::DidOpen()`.
342 void PdfViewWebPlugin::DidOpen(std::unique_ptr<UrlLoader> loader,
344 if (result == PP_OK) {
345 if (!engine()->HandleDocumentLoad(std::move(loader)))
346 DocumentLoadFailed();
352 void PdfViewWebPlugin::DidOpenPreview(std::unique_ptr<UrlLoader> loader,
357 } // namespace chrome_pdf