 Chromium Code Reviews
 Chromium Code Reviews Issue 1711103002:
  Implement lifetime observer on RenderWidgetHostViewBase.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master
    
  
    Issue 1711103002:
  Implement lifetime observer on RenderWidgetHostViewBase.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master| OLD | NEW | 
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 | 
| OLD | NEW |