| Index: content/browser/renderer_host/render_widget_host_input_event_router.cc
|
| diff --git a/content/browser/renderer_host/render_widget_host_input_event_router.cc b/content/browser/renderer_host/render_widget_host_input_event_router.cc
|
| index 92b07666a80d3b3c46a51db126c86faad0e43ccb..0137ce7250c155d840fe572ec633af75c5bebd49 100644
|
| --- a/content/browser/renderer_host/render_widget_host_input_event_router.cc
|
| +++ b/content/browser/renderer_host/render_widget_host_input_event_router.cc
|
| @@ -13,6 +13,31 @@
|
|
|
| namespace content {
|
|
|
| +void RenderWidgetHostInputEventRouter::OnRenderWidgetHostViewBaseDestroyed(
|
| + RenderWidgetHostViewBase* view) {
|
| + view->RemoveObserver(this);
|
| +
|
| + // Remove this view from the owner_map.
|
| + for (auto entry : owner_map_) {
|
| + if (entry.second == view) {
|
| + owner_map_.erase(entry.first);
|
| + // There will only be one instance of a particular view in the map.
|
| + break;
|
| + }
|
| + }
|
| +
|
| + if (view == current_touch_target_) {
|
| + current_touch_target_ = nullptr;
|
| + active_touches_ = 0;
|
| + }
|
| +}
|
| +
|
| +void RenderWidgetHostInputEventRouter::ClearAllObserverRegistrations() {
|
| + for (auto entry : owner_map_)
|
| + entry.second->RemoveObserver(this);
|
| + owner_map_.clear();
|
| +}
|
| +
|
| RenderWidgetHostInputEventRouter::HittestDelegate::HittestDelegate(
|
| const std::unordered_map<cc::SurfaceId, HittestData, cc::SurfaceIdHash>&
|
| hittest_data)
|
| @@ -37,10 +62,12 @@ bool RenderWidgetHostInputEventRouter::HittestDelegate::AcceptHitTarget(
|
| }
|
|
|
| RenderWidgetHostInputEventRouter::RenderWidgetHostInputEventRouter()
|
| - : active_touches_(0) {}
|
| + : current_touch_target_(nullptr), active_touches_(0) {}
|
|
|
| RenderWidgetHostInputEventRouter::~RenderWidgetHostInputEventRouter() {
|
| - owner_map_.clear();
|
| + // We may be destroyed before some of the owners in the map, so we must
|
| + // remove ourself from their observer lists.
|
| + ClearAllObserverRegistrations();
|
| }
|
|
|
| RenderWidgetHostViewBase* RenderWidgetHostInputEventRouter::FindEventTarget(
|
| @@ -71,12 +98,8 @@ RenderWidgetHostViewBase* RenderWidgetHostInputEventRouter::FindEventTarget(
|
| // parent frame has not sent a new compositor frame since that happened.
|
| if (iter == owner_map_.end())
|
| return root_view;
|
| - RenderWidgetHostViewBase* target = iter->second.get();
|
| - // If we find the weak pointer is now null, it means the map entry is stale
|
| - // and should be removed to free space.
|
| - if (!target)
|
| - owner_map_.erase(iter);
|
| - return target;
|
| +
|
| + return iter->second;
|
| }
|
|
|
| void RenderWidgetHostInputEventRouter::RouteMouseEvent(
|
| @@ -122,14 +145,10 @@ void RenderWidgetHostInputEventRouter::RouteTouchEvent(
|
| gfx::Point transformed_point;
|
| gfx::Point original_point(event->touches[0].position.x,
|
| event->touches[0].position.y);
|
| - RenderWidgetHostViewBase* target =
|
| + current_touch_target_ =
|
| FindEventTarget(root_view, original_point, &transformed_point);
|
| - if (!target)
|
| + if (!current_touch_target_)
|
| return;
|
| -
|
| - // Store the weak-ptr to the target, since it could disappear in the
|
| - // middle of a touch sequence.
|
| - current_touch_target_ = target->GetWeakPtr();
|
| }
|
| ++active_touches_;
|
| if (current_touch_target_)
|
| @@ -142,12 +161,14 @@ void RenderWidgetHostInputEventRouter::RouteTouchEvent(
|
| break;
|
| case blink::WebInputEvent::TouchEnd:
|
| case blink::WebInputEvent::TouchCancel:
|
| + if (!current_touch_target_)
|
| + break;
|
| +
|
| DCHECK(active_touches_);
|
| - if (current_touch_target_)
|
| - current_touch_target_->ProcessTouchEvent(*event, latency);
|
| + current_touch_target_->ProcessTouchEvent(*event, latency);
|
| --active_touches_;
|
| if (!active_touches_)
|
| - current_touch_target_ = WeakTarget();
|
| + current_touch_target_ = nullptr;
|
| break;
|
| default:
|
| NOTREACHED();
|
| @@ -158,12 +179,19 @@ void RenderWidgetHostInputEventRouter::AddSurfaceIdNamespaceOwner(
|
| uint32_t id,
|
| RenderWidgetHostViewBase* owner) {
|
| DCHECK(owner_map_.find(id) == owner_map_.end());
|
| - owner_map_.insert(std::make_pair(id, owner->GetWeakPtr()));
|
| + // We want to be notified if the owner is destroyed so we can remove it from
|
| + // our map.
|
| + owner->AddObserver(this);
|
| + owner_map_.insert(std::make_pair(id, owner));
|
| }
|
|
|
| void RenderWidgetHostInputEventRouter::RemoveSurfaceIdNamespaceOwner(
|
| uint32_t id) {
|
| - owner_map_.erase(id);
|
| + auto it_to_remove = owner_map_.find(id);
|
| + if (it_to_remove != owner_map_.end()) {
|
| + it_to_remove->second->RemoveObserver(this);
|
| + owner_map_.erase(it_to_remove);
|
| + }
|
|
|
| for (auto it = hittest_data_.begin(); it != hittest_data_.end();) {
|
| if (cc::SurfaceIdAllocator::NamespaceForId(it->first) == id)
|
|
|