Index: content/renderer/browser_plugin/browser_plugin_manager.cc |
diff --git a/content/renderer/browser_plugin/browser_plugin_manager.cc b/content/renderer/browser_plugin/browser_plugin_manager.cc |
index 9cde47387883186a2913d9e515aa6f08ed9694b3..587e8021b67f27b8aa32dbfa5786a320d2ebc647 100644 |
--- a/content/renderer/browser_plugin/browser_plugin_manager.cc |
+++ b/content/renderer/browser_plugin/browser_plugin_manager.cc |
@@ -3,7 +3,10 @@ |
// found in the LICENSE file. |
#include "content/renderer/browser_plugin/browser_plugin_manager.h" |
+ |
#include "base/memory/scoped_ptr.h" |
+#include "base/threading/thread.h" |
+#include "cc/base/completion_event.h" |
#include "content/common/browser_plugin/browser_plugin_constants.h" |
#include "content/common/browser_plugin/browser_plugin_messages.h" |
#include "content/common/frame_messages.h" |
@@ -11,9 +14,59 @@ |
#include "content/renderer/browser_plugin/browser_plugin.h" |
#include "content/renderer/render_thread_impl.h" |
#include "ipc/ipc_message_macros.h" |
+#include "ipc/ipc_sync_channel.h" |
+#include "ipc/message_filter.h" |
namespace content { |
+class GuestScrollCompletionFilter : public IPC::MessageFilter { |
+ public: |
+ explicit GuestScrollCompletionFilter( |
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner) |
+ : io_task_runner_(io_task_runner), |
+ guest_handled_scroll_event_(true), |
+ scroll_completion_event_(nullptr) {} |
+ |
+ // IPC::MessageFilter implementation. |
+ bool OnMessageReceived(const IPC::Message& message) override { |
+ DCHECK(io_task_runner_->BelongsToCurrentThread()); |
+ // If we see the as-yet-to-be determined ack from the browser, |
+ // set |guest_handled_scroll_event_| and call |
+ // scroll_completion_event_->Signal(). |
+ bool handled = true; |
+ IPC_BEGIN_MESSAGE_MAP(GuestScrollCompletionFilter, message) |
+ IPC_MESSAGE_HANDLER(BrowserPluginMsg_SignalScrollCompletionEvent, |
+ OnSignalScrollCompletionEvent) |
+ IPC_MESSAGE_UNHANDLED(handled = false) |
+ IPC_END_MESSAGE_MAP() |
+ return handled; |
+ } |
+ |
+ void set_scroll_completion_event( |
+ cc::CompletionEvent* scroll_completion_event) { |
+ scroll_completion_event_ = scroll_completion_event; |
+ } |
+ bool guest_handled_scroll_event() const { |
+ return guest_handled_scroll_event_; |
+ } |
+ |
+ private: |
+ ~GuestScrollCompletionFilter() override {} |
+ |
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; |
+ bool guest_handled_scroll_event_; |
+ cc::CompletionEvent* scroll_completion_event_; |
+ |
+ void OnSignalScrollCompletionEvent(bool handled) { |
+ DCHECK(io_task_runner_->BelongsToCurrentThread()); |
+ guest_handled_scroll_event_ = handled; |
+ scroll_completion_event_->Signal(); |
+ scroll_completion_event_ = nullptr; |
+ } |
+ |
+ DISALLOW_COPY_AND_ASSIGN(GuestScrollCompletionFilter); |
+}; |
+ |
// static |
BrowserPluginManager* BrowserPluginManager::Get() { |
if (!RenderThreadImpl::current()) |
@@ -27,6 +80,13 @@ BrowserPluginManager::BrowserPluginManager() { |
BrowserPluginManager::~BrowserPluginManager() { |
} |
+void BrowserPluginManager::Init( |
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, |
+ IPC::SyncChannel* channel) { |
+ scroll_completion_filter_ = new GuestScrollCompletionFilter(io_task_runner); |
+ channel->AddFilter(scroll_completion_filter_.get()); |
+} |
+ |
void BrowserPluginManager::AddBrowserPlugin( |
int browser_plugin_instance_id, |
BrowserPlugin* browser_plugin) { |
@@ -113,6 +173,15 @@ bool BrowserPluginManager::Send(IPC::Message* msg) { |
return RenderThreadImpl::current()->Send(msg); |
} |
+bool BrowserPluginManager::GetScrollHandledStatus() { |
+ cc::CompletionEvent scroll_completion_event; |
+ |
+ scroll_completion_filter_->set_scroll_completion_event( |
+ &scroll_completion_event); |
+ scroll_completion_event.Wait(); |
+ return scroll_completion_filter_->guest_handled_scroll_event(); |
+} |
+ |
void BrowserPluginManager::OnCompositorFrameSwappedPluginUnavailable( |
const IPC::Message& message) { |
BrowserPluginMsg_CompositorFrameSwapped::Param param; |