0

[unseasoned-pdf] Implement message posting from the plugin

Implement PostMessageSender to enable the plugin to post message events
to its embedder.

Note: The introduced implementation assumes messages are posted from the
renderer main thread, but the final implementation will be posting
messages from dedicated plugin threads.

Bug: 1109796
Change-Id: Id3737077e0ba5b82c9a8e5e6c6358e4081700b66
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2601112
Commit-Queue: Daniel Hosseinian <dhoss@chromium.org>
Reviewed-by: Jochen Eisinger <jochen@chromium.org>
Reviewed-by: K. Moon <kmoon@chromium.org>
Cr-Commit-Position: refs/heads/master@{#851787}
This commit is contained in:
Daniel Hosseinian
2021-02-08 18:08:06 +00:00
committed by Chromium LUCI CQ
parent 35c4378bf9
commit 11086ddf26
5 changed files with 115 additions and 0 deletions

@ -275,6 +275,8 @@ if (enable_pdf) {
"pdf_view_web_plugin.h",
"post_message_receiver.cc",
"post_message_receiver.h",
"post_message_sender.cc",
"post_message_sender.h",
]
configs += [ ":pdf_common_config" ]

@ -130,6 +130,7 @@ bool PdfViewWebPlugin::Initialize(blink::WebPluginContainer* container) {
PerProcessInitializer::GetInstance().Acquire();
InitializeEngine(PDFiumFormFiller::ScriptOption::kNoJavaScript);
LoadUrl(stream_url, /*is_print_preview=*/false);
post_message_sender_.set_container(container_);
return true;
}
@ -142,6 +143,8 @@ void PdfViewWebPlugin::Destroy() {
}
container_ = nullptr;
post_message_sender_.set_container(nullptr);
delete this;
}

@ -9,6 +9,7 @@
#include "base/memory/weak_ptr.h"
#include "pdf/pdf_view_plugin_base.h"
#include "pdf/post_message_receiver.h"
#include "pdf/post_message_sender.h"
#include "pdf/ppapi_migration/url_loader.h"
#include "third_party/blink/public/web/web_plugin.h"
#include "third_party/blink/public/web/web_plugin_params.h"
@ -146,6 +147,7 @@ class PdfViewWebPlugin final : public PdfViewPluginBase,
blink::WebPluginContainer* container_ = nullptr;
v8::Persistent<v8::Object> scriptable_receiver_;
PostMessageSender post_message_sender_;
base::WeakPtrFactory<PdfViewWebPlugin> weak_factory_{this};
};

@ -0,0 +1,51 @@
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "pdf/post_message_sender.h"
#include <memory>
#include "base/check_op.h"
#include "base/values.h"
#include "content/public/renderer/v8_value_converter.h"
#include "third_party/blink/public/web/blink.h"
#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_dom_message_event.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_plugin_container.h"
#include "third_party/blink/public/web/web_serialized_script_value.h"
#include "v8/include/v8.h"
namespace chrome_pdf {
PostMessageSender::PostMessageSender() : isolate_(blink::MainThreadIsolate()) {}
PostMessageSender::~PostMessageSender() = default;
// TODO(crbug.com/1109796): This method is currently called from the renderer
// main thread, but will be called from a dedicated plugin thread in the future.
// When that happens, the body of this method needs to be posted to the main
// thread as a task because that's where the Blink and V8 interactions need to
// occur.
void PostMessageSender::Post(base::Value message) {
// Drop messages if there is no container.
if (!container_)
return;
v8::HandleScope handle_scope(isolate_);
v8::Local<v8::Context> context =
container_->GetDocument().GetFrame()->MainWorldScriptContext();
DCHECK_EQ(isolate_, context->GetIsolate());
if (!v8_value_converter_)
v8_value_converter_ = content::V8ValueConverter::Create();
v8::Local<v8::Value> converted_message =
v8_value_converter_->ToV8Value(&message, context);
container_->EnqueueMessageEvent(
blink::WebSerializedScriptValue::Serialize(isolate_, converted_message));
}
} // namespace chrome_pdf

57
pdf/post_message_sender.h Normal file

@ -0,0 +1,57 @@
// Copyright 2021 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_POST_MESSAGE_SENDER_H_
#define PDF_POST_MESSAGE_SENDER_H_
#include <memory>
namespace base {
class Value;
} // namespace base
namespace blink {
class WebPluginContainer;
} // namespace blink
namespace content {
class V8ValueConverter;
} // namespace content
namespace v8 {
class Isolate;
} // namespace v8
namespace chrome_pdf {
// Manages messages sent from the plugin to its embedder.
class PostMessageSender final {
public:
PostMessageSender();
PostMessageSender(const PostMessageSender&) = delete;
PostMessageSender& operator=(const PostMessageSender&) = delete;
~PostMessageSender();
// Enqueues a "message" event carrying `message` to the plugin embedder.
// Nothing is enqueued if `container_` is null.
void Post(base::Value message);
// Sets the plugin container that enqueues the messages. This method should be
// called by the owning plugin whenever its container is set or unset to
// mirror the initialized lifetime of the plugin.
void set_container(blink::WebPluginContainer* container) {
container_ = container;
}
private:
std::unique_ptr<content::V8ValueConverter> v8_value_converter_;
v8::Isolate* isolate_;
blink::WebPluginContainer* container_ = nullptr;
};
} // namespace chrome_pdf
#endif // PDF_POST_MESSAGE_SENDER_H_