Commit 8410df4f authored by raymes's avatar raymes Committed by Commit bot

Prevent the in-process PDF plugin re-entering into JS during blink layout

Layout changes trigger view changes which get sent to the plugin. With the
in process plugin (PDF), the plugin is notified synchronously of the view
change. It then might execute scripts synchronously in the plugin but
scripts are not meant to be executed during layout changes. This change
runs the scripts asynchronously. I tested print preview to ensure that it
still works correctly.

Note that once we remove in-process plugins this won't be an issue because
view changes happen asynchronously out of process (besides the fact that
synchronous script execution is limited to private plugins).

BUG=351636

Review URL: https://codereview.chromium.org/530363002

Cr-Commit-Position: refs/heads/master@{#293256}
parent 972bc39f
......@@ -295,7 +295,7 @@ Instance::Instance(PP_Instance instance)
loader_factory_.Initialize(this);
timer_factory_.Initialize(this);
form_factory_.Initialize(this);
print_callback_factory_.Initialize(this);
callback_factory_.Initialize(this);
engine_.reset(PDFEngine::Create(this));
pp::Module::Get()->AddPluginInterface(kPPPPdfInterface, &ppp_private);
AddPerInstanceObject(kPPPPdfInterface, this);
......@@ -1132,8 +1132,12 @@ void Instance::Scroll(const pp::Point& point) {
if (page_indicator_.visible())
paint_manager_.InvalidateRect(page_indicator_.rect());
if (on_scroll_callback_.is_string())
ExecuteScript(on_scroll_callback_);
// Run the scroll callback asynchronously. This function can be invoked by a
// layout change which should not re-enter into JS synchronously.
pp::CompletionCallback callback =
callback_factory_.NewCallback(&Instance::RunCallback,
on_scroll_callback_);
pp::Module::Get()->core()->CallOnMainThread(0, callback);
}
void Instance::ScrollToX(int position) {
......@@ -1374,7 +1378,7 @@ void Instance::Print() {
}
pp::CompletionCallback callback =
print_callback_factory_.NewCallback(&Instance::OnPrint);
callback_factory_.NewCallback(&Instance::OnPrint);
pp::Module::Get()->core()->CallOnMainThread(0, callback);
}
......@@ -2117,8 +2121,17 @@ void Instance::OnGeometryChanged(double old_zoom, float old_device_scale) {
return;
paint_manager_.InvalidateRect(pp::Rect(pp::Point(), plugin_size_));
if (on_plugin_size_changed_callback_.is_string())
ExecuteScript(on_plugin_size_changed_callback_);
// Run the plugin size change callback asynchronously. This function can be
// invoked by a layout change which should not re-enter into JS synchronously.
pp::CompletionCallback callback =
callback_factory_.NewCallback(&Instance::RunCallback,
on_plugin_size_changed_callback_);
pp::Module::Get()->core()->CallOnMainThread(0, callback);
}
void Instance::RunCallback(int32_t, pp::Var callback) {
if (callback.is_string())
ExecuteScript(callback);
}
void Instance::CreateHorizontalScrollbar() {
......
......@@ -202,6 +202,9 @@ class Instance : public pp::InstancePrivate,
// scrollbars, background parts, and notifies the pdf engine.
void OnGeometryChanged(double old_zoom, float old_device_scale);
// Runs the given JS callback given in |callback|.
void RunCallback(int32_t, pp::Var callback);
void CreateHorizontalScrollbar();
void CreateVerticalScrollbar();
void DestroyHorizontalScrollbar();
......@@ -456,8 +459,10 @@ class Instance : public pp::InstancePrivate,
pp::CompletionCallbackFactory<Instance> form_factory_;
pp::URLLoader form_loader_;
// Used for printing without re-entrancy issues.
pp::CompletionCallbackFactory<Instance> print_callback_factory_;
// Used for generating callbacks.
// TODO(raymes): We don't really need other callback factories we can just
// fold them into this one.
pp::CompletionCallbackFactory<Instance> callback_factory_;
// True if we haven't painted the plugin viewport yet.
bool first_paint_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment