Commit 1963fcc8 authored by Dave Tapuska's avatar Dave Tapuska Committed by Commit Bot

Speculative fix for EventProcessor crash

Crash reports indicate that the EventDispatchDetails might actually be
wrong sometimes and that the EventProcessor is destroyed.

Add a weak ptr to trap the destruction of the current object.

BUG=763372

Change-Id: I5fec449221c962a6ce755cd3c69e62c2a0d3af9a
Reviewed-on: https://chromium-review.googlesource.com/658019Reviewed-by: default avatarScott Violet <sky@chromium.org>
Commit-Queue: Dave Tapuska <dtapuska@chromium.org>
Cr-Commit-Position: refs/heads/master@{#504194}
parent e050b53a
......@@ -9,7 +9,12 @@
namespace ui {
EventProcessor::EventProcessor() : weak_ptr_factory_(this) {}
EventProcessor::~EventProcessor() {}
EventDispatchDetails EventProcessor::OnEventFromSource(Event* event) {
base::WeakPtr<EventProcessor> weak_this = weak_ptr_factory_.GetWeakPtr();
// If |event| is in the process of being dispatched or has already been
// dispatched, then dispatch a copy of the event instead. We expect event
// target to be already set if event phase is after EP_PREDISPATCH.
......@@ -61,6 +66,11 @@ EventDispatchDetails EventProcessor::OnEventFromSource(Event* event) {
if (details.dispatcher_destroyed)
return details;
if (!weak_this) {
details.dispatcher_destroyed = true;
return details;
}
if (details.target_destroyed || event->handled() ||
target == initial_target) {
break;
......
......@@ -5,6 +5,7 @@
#ifndef UI_EVENTS_EVENT_PROCESSOR_H_
#define UI_EVENTS_EVENT_PROCESSOR_H_
#include "base/memory/weak_ptr.h"
#include "ui/events/event_dispatcher.h"
#include "ui/events/event_sink.h"
#include "ui/events/event_source.h"
......@@ -18,7 +19,8 @@ class EventTargeter;
class EVENTS_EXPORT EventProcessor : public EventDispatcherDelegate,
public EventSink {
public:
~EventProcessor() override {}
EventProcessor();
~EventProcessor() override;
// EventSink overrides:
EventDispatchDetails OnEventFromSource(Event* event) override;
......@@ -50,6 +52,10 @@ class EVENTS_EXPORT EventProcessor : public EventDispatcherDelegate,
// that the last target to which |event| was dispatched may have been
// destroyed.
virtual void OnEventProcessingFinished(Event* event);
private:
base::WeakPtrFactory<EventProcessor> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(EventProcessor);
};
} // namespace ui
......
......@@ -23,6 +23,40 @@ typedef std::vector<std::string> HandlerSequenceRecorder;
namespace ui {
namespace test {
class SelfDestroyingEventProcessor : public TestEventProcessor {
public:
SelfDestroyingEventProcessor() {}
protected:
EventDispatchDetails PostDispatchEvent(EventTarget* target,
const Event& event) override;
private:
DISALLOW_COPY_AND_ASSIGN(SelfDestroyingEventProcessor);
};
class SelfDestroyingTestEventTarget : public TestEventTarget {
public:
SelfDestroyingTestEventTarget()
: processor_(new SelfDestroyingEventProcessor()) {}
TestEventProcessor* processor() { return processor_.get(); }
void DestroyProcessor() { processor_.reset(); }
private:
std::unique_ptr<SelfDestroyingEventProcessor> processor_;
DISALLOW_COPY_AND_ASSIGN(SelfDestroyingTestEventTarget);
};
EventDispatchDetails SelfDestroyingEventProcessor::PostDispatchEvent(
EventTarget* target,
const Event& event) {
static_cast<SelfDestroyingTestEventTarget*>(target)->DestroyProcessor();
return EventDispatchDetails();
}
class EventProcessorTest : public testing::Test {
public:
EventProcessorTest() {}
......@@ -373,5 +407,19 @@ TEST_F(EventProcessorTest, HandlerSequence) {
expected, expected + arraysize(expected)), recorder);
}
TEST(EventProcessorCrashTest, Basic) {
std::unique_ptr<TestEventTarget> root(new TestEventTarget());
std::unique_ptr<SelfDestroyingTestEventTarget> target(
new SelfDestroyingTestEventTarget());
root->SetEventTargeter(
base::MakeUnique<TestEventTargeter>(target.get(), false));
TestEventProcessor* processor = target->processor();
processor->SetRoot(std::move(root));
MouseEvent mouse(ET_MOUSE_MOVED, gfx::Point(10, 10), gfx::Point(10, 10),
EventTimeForNow(), EF_NONE, EF_NONE);
EXPECT_TRUE(processor->OnEventFromSource(&mouse).dispatcher_destroyed);
}
} // namespace test
} // namespace ui
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