Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(260)

Side by Side Diff: content/browser/renderer_host/render_widget_host_input_event_router.cc

Issue 1711103002: Implement lifetime observer on RenderWidgetHostViewBase. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Restructure, and make RWHVB derived classes responsible for early notification. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/renderer_host/render_widget_host_input_event_router.h" 5 #include "content/browser/renderer_host/render_widget_host_input_event_router.h"
6 6
7 #include "cc/quads/surface_draw_quad.h" 7 #include "cc/quads/surface_draw_quad.h"
8 #include "cc/surfaces/surface_id_allocator.h" 8 #include "cc/surfaces/surface_id_allocator.h"
9 #include "cc/surfaces/surface_manager.h" 9 #include "cc/surfaces/surface_manager.h"
10 #include "content/browser/renderer_host/render_widget_host_view_base.h" 10 #include "content/browser/renderer_host/render_widget_host_view_base.h"
11 #include "content/common/frame_messages.h" 11 #include "content/common/frame_messages.h"
12 #include "third_party/WebKit/public/web/WebInputEvent.h" 12 #include "third_party/WebKit/public/web/WebInputEvent.h"
13 13
14 namespace content { 14 namespace content {
15 15
16 void RenderWidgetHostInputEventRouter::OnRenderWidgetHostViewBaseDestroyed(
17 RenderWidgetHostViewBase* view) {
18 view->RemoveObserver(this);
19
20 // Remove this view from the owner_map.
21 for (auto entry : owner_map_) {
22 if (entry.second == view) {
23 owner_map_.erase(entry.first);
24 // TODO(wjmaclean): Is it safe to assume a view will only have one
25 // surface, and hence only one entry in the map? If not, remove the
26 // next line.
kenrb 2016/02/22 17:05:10 Yes, it should be an invariant that a RWHV is only
wjmaclean 2016/02/23 13:13:26 Done.
27 break;
28 }
29 }
30
31 if (view == current_touch_target_) {
32 current_touch_target_ = nullptr;
33 active_touches_ = 0;
34 }
35 }
36
37 void RenderWidgetHostInputEventRouter::ClearAllObserverRegistrations() {
38 for (auto entry : owner_map_)
39 entry.second->RemoveObserver(this);
40 owner_map_.clear();
41 }
42
16 RenderWidgetHostInputEventRouter::HittestDelegate::HittestDelegate( 43 RenderWidgetHostInputEventRouter::HittestDelegate::HittestDelegate(
17 const std::unordered_map<cc::SurfaceId, HittestData, cc::SurfaceIdHash>& 44 const std::unordered_map<cc::SurfaceId, HittestData, cc::SurfaceIdHash>&
18 hittest_data) 45 hittest_data)
19 : hittest_data_(hittest_data) {} 46 : hittest_data_(hittest_data) {}
20 47
21 bool RenderWidgetHostInputEventRouter::HittestDelegate::RejectHitTarget( 48 bool RenderWidgetHostInputEventRouter::HittestDelegate::RejectHitTarget(
22 const cc::SurfaceDrawQuad* surface_quad, 49 const cc::SurfaceDrawQuad* surface_quad,
23 const gfx::Point& point_in_quad_space) { 50 const gfx::Point& point_in_quad_space) {
24 auto it = hittest_data_.find(surface_quad->surface_id); 51 auto it = hittest_data_.find(surface_quad->surface_id);
25 if (it != hittest_data_.end() && it->second.ignored_for_hittest) 52 if (it != hittest_data_.end() && it->second.ignored_for_hittest)
26 return true; 53 return true;
27 return false; 54 return false;
28 } 55 }
29 56
30 bool RenderWidgetHostInputEventRouter::HittestDelegate::AcceptHitTarget( 57 bool RenderWidgetHostInputEventRouter::HittestDelegate::AcceptHitTarget(
31 const cc::SurfaceDrawQuad* surface_quad, 58 const cc::SurfaceDrawQuad* surface_quad,
32 const gfx::Point& point_in_quad_space) { 59 const gfx::Point& point_in_quad_space) {
33 auto it = hittest_data_.find(surface_quad->surface_id); 60 auto it = hittest_data_.find(surface_quad->surface_id);
34 if (it != hittest_data_.end() && !it->second.ignored_for_hittest) 61 if (it != hittest_data_.end() && !it->second.ignored_for_hittest)
35 return true; 62 return true;
36 return false; 63 return false;
37 } 64 }
38 65
39 RenderWidgetHostInputEventRouter::RenderWidgetHostInputEventRouter() 66 RenderWidgetHostInputEventRouter::RenderWidgetHostInputEventRouter()
40 : active_touches_(0) {} 67 : current_touch_target_(nullptr), active_touches_(0) {}
41 68
42 RenderWidgetHostInputEventRouter::~RenderWidgetHostInputEventRouter() { 69 RenderWidgetHostInputEventRouter::~RenderWidgetHostInputEventRouter() {
43 owner_map_.clear(); 70 // We may be destroyed before some of the owners in the map, so we must
71 // remove ourself from their observer lists.
72 ClearAllObserverRegistrations();
44 } 73 }
45 74
46 RenderWidgetHostViewBase* RenderWidgetHostInputEventRouter::FindEventTarget( 75 RenderWidgetHostViewBase* RenderWidgetHostInputEventRouter::FindEventTarget(
47 RenderWidgetHostViewBase* root_view, 76 RenderWidgetHostViewBase* root_view,
48 const gfx::Point& point, 77 const gfx::Point& point,
49 gfx::Point* transformed_point) { 78 gfx::Point* transformed_point) {
50 // Short circuit if owner_map has only one RenderWidgetHostView, no need for 79 // Short circuit if owner_map has only one RenderWidgetHostView, no need for
51 // hit testing. 80 // hit testing.
52 if (owner_map_.size() <= 1) { 81 if (owner_map_.size() <= 1) {
53 *transformed_point = point; 82 *transformed_point = point;
(...skipping 10 matching lines...) Expand all
64 // single process with only one RenderWidgetHost. 93 // single process with only one RenderWidgetHost.
65 uint32_t surface_id_namespace = 94 uint32_t surface_id_namespace =
66 root_view->SurfaceIdNamespaceAtPoint(&delegate, point, transformed_point); 95 root_view->SurfaceIdNamespaceAtPoint(&delegate, point, transformed_point);
67 const SurfaceIdNamespaceOwnerMap::iterator iter = 96 const SurfaceIdNamespaceOwnerMap::iterator iter =
68 owner_map_.find(surface_id_namespace); 97 owner_map_.find(surface_id_namespace);
69 // If the point hit a Surface whose namspace is no longer in the map, then 98 // If the point hit a Surface whose namspace is no longer in the map, then
70 // it likely means the RenderWidgetHostView has been destroyed but its 99 // it likely means the RenderWidgetHostView has been destroyed but its
71 // parent frame has not sent a new compositor frame since that happened. 100 // parent frame has not sent a new compositor frame since that happened.
72 if (iter == owner_map_.end()) 101 if (iter == owner_map_.end())
73 return root_view; 102 return root_view;
74 RenderWidgetHostViewBase* target = iter->second.get(); 103
75 // If we find the weak pointer is now null, it means the map entry is stale 104 return iter->second;
76 // and should be removed to free space.
77 if (!target)
78 owner_map_.erase(iter);
79 return target;
80 } 105 }
81 106
82 void RenderWidgetHostInputEventRouter::RouteMouseEvent( 107 void RenderWidgetHostInputEventRouter::RouteMouseEvent(
83 RenderWidgetHostViewBase* root_view, 108 RenderWidgetHostViewBase* root_view,
84 blink::WebMouseEvent* event) { 109 blink::WebMouseEvent* event) {
85 gfx::Point transformed_point; 110 gfx::Point transformed_point;
86 RenderWidgetHostViewBase* target = FindEventTarget( 111 RenderWidgetHostViewBase* target = FindEventTarget(
87 root_view, gfx::Point(event->x, event->y), &transformed_point); 112 root_view, gfx::Point(event->x, event->y), &transformed_point);
88 if (!target) 113 if (!target)
89 return; 114 return;
(...skipping 25 matching lines...) Expand all
115 const ui::LatencyInfo& latency) { 140 const ui::LatencyInfo& latency) {
116 switch (event->type) { 141 switch (event->type) {
117 case blink::WebInputEvent::TouchStart: { 142 case blink::WebInputEvent::TouchStart: {
118 if (!active_touches_) { 143 if (!active_touches_) {
119 // Since this is the first touch, it defines the target for the rest 144 // Since this is the first touch, it defines the target for the rest
120 // of this sequence. 145 // of this sequence.
121 DCHECK(!current_touch_target_); 146 DCHECK(!current_touch_target_);
122 gfx::Point transformed_point; 147 gfx::Point transformed_point;
123 gfx::Point original_point(event->touches[0].position.x, 148 gfx::Point original_point(event->touches[0].position.x,
124 event->touches[0].position.y); 149 event->touches[0].position.y);
125 RenderWidgetHostViewBase* target = 150 current_touch_target_ =
126 FindEventTarget(root_view, original_point, &transformed_point); 151 FindEventTarget(root_view, original_point, &transformed_point);
127 if (!target) 152 if (!current_touch_target_)
128 return; 153 return;
129
130 // Store the weak-ptr to the target, since it could disappear in the
131 // middle of a touch sequence.
132 current_touch_target_ = target->GetWeakPtr();
133 } 154 }
134 ++active_touches_; 155 ++active_touches_;
135 if (current_touch_target_) 156 if (current_touch_target_)
136 current_touch_target_->ProcessTouchEvent(*event, latency); 157 current_touch_target_->ProcessTouchEvent(*event, latency);
137 break; 158 break;
138 } 159 }
139 case blink::WebInputEvent::TouchMove: 160 case blink::WebInputEvent::TouchMove:
140 if (current_touch_target_) 161 if (current_touch_target_)
141 current_touch_target_->ProcessTouchEvent(*event, latency); 162 current_touch_target_->ProcessTouchEvent(*event, latency);
142 break; 163 break;
143 case blink::WebInputEvent::TouchEnd: 164 case blink::WebInputEvent::TouchEnd:
144 case blink::WebInputEvent::TouchCancel: 165 case blink::WebInputEvent::TouchCancel:
166 if (!current_touch_target_)
167 break;
168
145 DCHECK(active_touches_); 169 DCHECK(active_touches_);
146 if (current_touch_target_) 170 current_touch_target_->ProcessTouchEvent(*event, latency);
147 current_touch_target_->ProcessTouchEvent(*event, latency);
148 --active_touches_; 171 --active_touches_;
149 if (!active_touches_) 172 if (!active_touches_)
150 current_touch_target_ = WeakTarget(); 173 current_touch_target_ = nullptr;
151 break; 174 break;
152 default: 175 default:
153 NOTREACHED(); 176 NOTREACHED();
154 } 177 }
155 } 178 }
156 179
157 void RenderWidgetHostInputEventRouter::AddSurfaceIdNamespaceOwner( 180 void RenderWidgetHostInputEventRouter::AddSurfaceIdNamespaceOwner(
158 uint32_t id, 181 uint32_t id,
159 RenderWidgetHostViewBase* owner) { 182 RenderWidgetHostViewBase* owner) {
160 DCHECK(owner_map_.find(id) == owner_map_.end()); 183 DCHECK(owner_map_.find(id) == owner_map_.end());
161 owner_map_.insert(std::make_pair(id, owner->GetWeakPtr())); 184 // We want to be notified if the owner is destroyed so we can remove it from
185 // our map.
186 owner->AddObserver(this);
187 owner_map_.insert(std::make_pair(id, owner));
162 } 188 }
163 189
164 void RenderWidgetHostInputEventRouter::RemoveSurfaceIdNamespaceOwner( 190 void RenderWidgetHostInputEventRouter::RemoveSurfaceIdNamespaceOwner(
165 uint32_t id) { 191 uint32_t id) {
166 owner_map_.erase(id); 192 auto it_to_remove = owner_map_.find(id);
193 if (it_to_remove != owner_map_.end()) {
194 it_to_remove->second->RemoveObserver(this);
195 owner_map_.erase(it_to_remove);
196 }
167 197
168 for (auto it = hittest_data_.begin(); it != hittest_data_.end();) { 198 for (auto it = hittest_data_.begin(); it != hittest_data_.end();) {
169 if (cc::SurfaceIdAllocator::NamespaceForId(it->first) == id) 199 if (cc::SurfaceIdAllocator::NamespaceForId(it->first) == id)
170 it = hittest_data_.erase(it); 200 it = hittest_data_.erase(it);
171 else 201 else
172 ++it; 202 ++it;
173 } 203 }
174 } 204 }
175 205
176 void RenderWidgetHostInputEventRouter::OnHittestData( 206 void RenderWidgetHostInputEventRouter::OnHittestData(
177 const FrameHostMsg_HittestData_Params& params) { 207 const FrameHostMsg_HittestData_Params& params) {
178 if (owner_map_.find(cc::SurfaceIdAllocator::NamespaceForId( 208 if (owner_map_.find(cc::SurfaceIdAllocator::NamespaceForId(
179 params.surface_id)) == owner_map_.end()) { 209 params.surface_id)) == owner_map_.end()) {
180 return; 210 return;
181 } 211 }
182 HittestData data; 212 HittestData data;
183 data.ignored_for_hittest = params.ignored_for_hittest; 213 data.ignored_for_hittest = params.ignored_for_hittest;
184 hittest_data_[params.surface_id] = data; 214 hittest_data_[params.surface_id] = data;
185 } 215 }
186 216
187 } // namespace content 217 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698