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

Side by Side Diff: components/mus/public/cpp/lib/window_tree_client_impl.cc

Issue 1982333002: Candidate fix for observe-window-after-free error in WindowTreeClientImpl::LocalSetCapture (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Guard observer's AddObserver invocation Created 4 years, 7 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
« no previous file with comments | « components/mus/public/cpp/lib/window_tree_client_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "components/mus/public/cpp/lib/window_tree_client_impl.h" 5 #include "components/mus/public/cpp/lib/window_tree_client_impl.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <string> 9 #include <string>
10 #include <utility> 10 #include <utility>
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 mojo::InterfaceRequest<mojom::WindowTreeClient> request, 113 mojo::InterfaceRequest<mojom::WindowTreeClient> request,
114 CreateType create_type, 114 CreateType create_type,
115 WindowManagerDelegate* window_manager_delegate) { 115 WindowManagerDelegate* window_manager_delegate) {
116 WindowTreeClientImpl* client = new WindowTreeClientImpl( 116 WindowTreeClientImpl* client = new WindowTreeClientImpl(
117 delegate, window_manager_delegate, std::move(request)); 117 delegate, window_manager_delegate, std::move(request));
118 if (create_type == CreateType::WAIT_FOR_EMBED) 118 if (create_type == CreateType::WAIT_FOR_EMBED)
119 client->WaitForEmbed(); 119 client->WaitForEmbed();
120 return client; 120 return client;
121 } 121 }
122 122
123 class WindowTreeClientImpl::MusWindowObserver : public mus::WindowObserver {
124 public:
125 explicit MusWindowObserver(Window* window)
126 : window_(window) {}
127
128 ~MusWindowObserver() override {
129 if (window_)
130 window_->RemoveObserver(this);
131 }
132
133 void SetWindow(Window* window) {
134 if (window_ == window)
135 return;
136
137 if (window_)
138 window_->RemoveObserver(this);
139 window_ = window;
140 if (window_)
141 window_->AddObserver(this);
142 }
143
144 // mus::WindowObserver:
145 void OnWindowDestroying(Window* window) override {
146 DCHECK_EQ(window_, window);
147 window_->RemoveObserver(this);
148 window_ = nullptr;
149 }
150
151 Window* window() { return window_; }
152
153 private:
154 Window* window_;
155
156 DISALLOW_COPY_AND_ASSIGN(MusWindowObserver);
157 };
158
123 WindowTreeClientImpl::WindowTreeClientImpl( 159 WindowTreeClientImpl::WindowTreeClientImpl(
124 WindowTreeDelegate* delegate, 160 WindowTreeDelegate* delegate,
125 WindowManagerDelegate* window_manager_delegate, 161 WindowManagerDelegate* window_manager_delegate,
126 mojo::InterfaceRequest<mojom::WindowTreeClient> request) 162 mojo::InterfaceRequest<mojom::WindowTreeClient> request)
127 : connection_id_(0), 163 : connection_id_(0),
128 next_window_id_(1), 164 next_window_id_(1),
129 next_change_id_(1), 165 next_change_id_(1),
130 delegate_(delegate), 166 delegate_(delegate),
131 window_manager_delegate_(window_manager_delegate), 167 window_manager_delegate_(window_manager_delegate),
132 capture_window_(nullptr), 168 capture_window_observer_(new MusWindowObserver(nullptr)),
133 focused_window_(nullptr), 169 focused_window_(nullptr),
134 binding_(this), 170 binding_(this),
135 tree_(nullptr), 171 tree_(nullptr),
136 delete_on_no_roots_(true), 172 delete_on_no_roots_(true),
137 in_destructor_(false), 173 in_destructor_(false),
138 cursor_location_memory_(nullptr), 174 cursor_location_memory_(nullptr),
139 weak_factory_(this) { 175 weak_factory_(this) {
140 // Allow for a null request in tests. 176 // Allow for a null request in tests.
141 if (request.is_pending()) 177 if (request.is_pending())
142 binding_.Bind(std::move(request)); 178 binding_.Bind(std::move(request));
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 226
191 void WindowTreeClientImpl::WaitForEmbed() { 227 void WindowTreeClientImpl::WaitForEmbed() {
192 DCHECK(roots_.empty()); 228 DCHECK(roots_.empty());
193 // OnEmbed() is the first function called. 229 // OnEmbed() is the first function called.
194 binding_.WaitForIncomingMethodCall(); 230 binding_.WaitForIncomingMethodCall();
195 // TODO(sky): deal with pipe being closed before we get OnEmbed(). 231 // TODO(sky): deal with pipe being closed before we get OnEmbed().
196 } 232 }
197 233
198 void WindowTreeClientImpl::DestroyWindow(Window* window) { 234 void WindowTreeClientImpl::DestroyWindow(Window* window) {
199 // TODO(jonross): Also clear the focused window (crbug.com/611983) 235 // TODO(jonross): Also clear the focused window (crbug.com/611983)
200 if (window == capture_window_) { 236 if (window == capture_window_observer_->window()) {
201 InFlightCaptureChange reset_change(this, nullptr); 237 InFlightCaptureChange reset_change(this, nullptr);
202 ApplyServerChangeToExistingInFlightChange(reset_change); 238 ApplyServerChangeToExistingInFlightChange(reset_change);
203 // Normally just updating the queued changes is sufficient. However since 239 // Normally just updating the queued changes is sufficient. However since
204 // |window| is being destroyed, it will not be possible to notify its 240 // |window| is being destroyed, it will not be possible to notify its
205 // observers 241 // observers
206 // of the lost capture. Update local state now. 242 // of the lost capture. Update local state now.
207 LocalSetCapture(nullptr); 243 LocalSetCapture(nullptr);
208 } 244 }
209 DCHECK(tree_); 245 DCHECK(tree_);
210 const uint32_t change_id = ScheduleInFlightChange(base::WrapUnique( 246 const uint32_t change_id = ScheduleInFlightChange(base::WrapUnique(
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 const uint32_t change_id = ScheduleInFlightChange( 309 const uint32_t change_id = ScheduleInFlightChange(
274 base::WrapUnique(new InFlightBoundsChange(window, old_bounds))); 310 base::WrapUnique(new InFlightBoundsChange(window, old_bounds)));
275 tree_->SetWindowBounds(change_id, server_id(window), 311 tree_->SetWindowBounds(change_id, server_id(window),
276 mojo::Rect::From(bounds)); 312 mojo::Rect::From(bounds));
277 } 313 }
278 314
279 void WindowTreeClientImpl::SetCapture(Window* window) { 315 void WindowTreeClientImpl::SetCapture(Window* window) {
280 // In order for us to get here we had to have exposed a window, which implies 316 // In order for us to get here we had to have exposed a window, which implies
281 // we got a connection. 317 // we got a connection.
282 DCHECK(tree_); 318 DCHECK(tree_);
283 if (capture_window_ == window) 319 if (capture_window_observer_->window() == window)
284 return; 320 return;
285 const uint32_t change_id = ScheduleInFlightChange( 321 const uint32_t change_id = ScheduleInFlightChange(
286 base::WrapUnique(new InFlightCaptureChange(this, capture_window_))); 322 base::WrapUnique(
323 new InFlightCaptureChange(this, capture_window_observer_->window())));
287 tree_->SetCapture(change_id, server_id(window)); 324 tree_->SetCapture(change_id, server_id(window));
288 LocalSetCapture(window); 325 LocalSetCapture(window);
289 } 326 }
290 327
291 void WindowTreeClientImpl::ReleaseCapture(Window* window) { 328 void WindowTreeClientImpl::ReleaseCapture(Window* window) {
292 // In order for us to get here we had to have exposed a window, which implies 329 // In order for us to get here we had to have exposed a window, which implies
293 // we got a connection. 330 // we got a connection.
294 DCHECK(tree_); 331 DCHECK(tree_);
295 if (capture_window_ != window) 332 if (capture_window_observer_->window() != window)
296 return; 333 return;
297 const uint32_t change_id = ScheduleInFlightChange( 334 const uint32_t change_id = ScheduleInFlightChange(
298 base::WrapUnique(new InFlightCaptureChange(this, window))); 335 base::WrapUnique(new InFlightCaptureChange(this, window)));
299 tree_->ReleaseCapture(change_id, server_id(window)); 336 tree_->ReleaseCapture(change_id, server_id(window));
300 LocalSetCapture(nullptr); 337 LocalSetCapture(nullptr);
301 } 338 }
302 339
303 void WindowTreeClientImpl::SetClientArea( 340 void WindowTreeClientImpl::SetClientArea(
304 Id window_id, 341 Id window_id,
305 const gfx::Insets& client_area, 342 const gfx::Insets& client_area,
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 void WindowTreeClientImpl::AttachSurface( 435 void WindowTreeClientImpl::AttachSurface(
399 Id window_id, 436 Id window_id,
400 mojom::SurfaceType type, 437 mojom::SurfaceType type,
401 mojo::InterfaceRequest<mojom::Surface> surface, 438 mojo::InterfaceRequest<mojom::Surface> surface,
402 mojom::SurfaceClientPtr client) { 439 mojom::SurfaceClientPtr client) {
403 DCHECK(tree_); 440 DCHECK(tree_);
404 tree_->AttachSurface(window_id, type, std::move(surface), std::move(client)); 441 tree_->AttachSurface(window_id, type, std::move(surface), std::move(client));
405 } 442 }
406 443
407 void WindowTreeClientImpl::LocalSetCapture(Window* window) { 444 void WindowTreeClientImpl::LocalSetCapture(Window* window) {
408 if (capture_window_ == window) 445 if (capture_window_observer_->window() == window)
409 return; 446 return;
410 Window* lost_capture = capture_window_; 447 Window* lost_capture = capture_window_observer_->window();
411 capture_window_ = window; 448 capture_window_observer_->SetWindow(window);
412 if (lost_capture) { 449 if (lost_capture) {
413 FOR_EACH_OBSERVER(WindowObserver, *WindowPrivate(lost_capture).observers(), 450 FOR_EACH_OBSERVER(WindowObserver, *WindowPrivate(lost_capture).observers(),
414 OnWindowLostCapture(lost_capture)); 451 OnWindowLostCapture(lost_capture));
415 } 452 }
416 } 453 }
417 454
418 void WindowTreeClientImpl::LocalSetFocus(Window* focused) { 455 void WindowTreeClientImpl::LocalSetFocus(Window* focused) {
419 Window* blurred = focused_window_; 456 Window* blurred = focused_window_;
420 // Update |focused_window_| before calling any of the observers, so that the 457 // Update |focused_window_| before calling any of the observers, so that the
421 // observers get the correct result from calling |Window::HasFocus()|, 458 // observers get the correct result from calling |Window::HasFocus()|,
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after
857 WindowPrivate(window).LocalReorder(relative_window, direction); 894 WindowPrivate(window).LocalReorder(relative_window, direction);
858 } 895 }
859 896
860 void WindowTreeClientImpl::OnWindowDeleted(Id window_id) { 897 void WindowTreeClientImpl::OnWindowDeleted(Id window_id) {
861 Window* window = GetWindowByServerId(window_id); 898 Window* window = GetWindowByServerId(window_id);
862 if (window) 899 if (window)
863 WindowPrivate(window).LocalDestroy(); 900 WindowPrivate(window).LocalDestroy();
864 } 901 }
865 902
866 Window* WindowTreeClientImpl::GetCaptureWindow() { 903 Window* WindowTreeClientImpl::GetCaptureWindow() {
867 return capture_window_; 904 return capture_window_observer_->window();
868 } 905 }
869 906
870 void WindowTreeClientImpl::OnWindowVisibilityChanged(Id window_id, 907 void WindowTreeClientImpl::OnWindowVisibilityChanged(Id window_id,
871 bool visible) { 908 bool visible) {
872 Window* window = GetWindowByServerId(window_id); 909 Window* window = GetWindowByServerId(window_id);
873 if (!window) 910 if (!window)
874 return; 911 return;
875 912
876 InFlightVisibleChange new_change(window, visible); 913 InFlightVisibleChange new_change(window, visible);
877 if (ApplyServerChangeToExistingInFlightChange(new_change)) 914 if (ApplyServerChangeToExistingInFlightChange(new_change))
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
1109 1146
1110 void WindowTreeClientImpl::SetUnderlaySurfaceOffsetAndExtendedHitArea( 1147 void WindowTreeClientImpl::SetUnderlaySurfaceOffsetAndExtendedHitArea(
1111 Window* window, 1148 Window* window,
1112 const gfx::Vector2d& offset, 1149 const gfx::Vector2d& offset,
1113 const gfx::Insets& hit_area) { 1150 const gfx::Insets& hit_area) {
1114 window_manager_internal_client_->SetUnderlaySurfaceOffsetAndExtendedHitArea( 1151 window_manager_internal_client_->SetUnderlaySurfaceOffsetAndExtendedHitArea(
1115 server_id(window), offset.x(), offset.y(), mojo::Insets::From(hit_area)); 1152 server_id(window), offset.x(), offset.y(), mojo::Insets::From(hit_area));
1116 } 1153 }
1117 1154
1118 } // namespace mus 1155 } // namespace mus
OLDNEW
« no previous file with comments | « components/mus/public/cpp/lib/window_tree_client_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698