From afba61456205f2254c7b69f74e92857b3b51a856 Mon Sep 17 00:00:00 2001 From: shuchen Date: Tue, 2 Sep 2014 10:03:38 -0700 Subject: [PATCH] Fix the issue that GetFrameWindow() may change between AddObserver and RemoveObserver in KeyboardController. BUG=408995 TEST=Verified on linux_chromeos. Review URL: https://codereview.chromium.org/527153002 Cr-Commit-Position: refs/heads/master@{#292949} --- ui/keyboard/keyboard_controller.cc | 43 +++++++++++++++++++----------- ui/keyboard/keyboard_controller.h | 3 +-- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/ui/keyboard/keyboard_controller.cc b/ui/keyboard/keyboard_controller.cc index ceef5941f7e42..6c02069e7ff6e 100644 --- a/ui/keyboard/keyboard_controller.cc +++ b/ui/keyboard/keyboard_controller.cc @@ -4,6 +4,8 @@ #include "ui/keyboard/keyboard_controller.h" +#include + #include "base/bind.h" #include "base/command_line.h" #include "content/public/browser/render_widget_host.h" @@ -207,6 +209,12 @@ class WindowBoundsChangeObserver : public aura::WindowObserver { const gfx::Rect& old_bounds, const gfx::Rect& new_bounds) OVERRIDE; virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE; + + void AddObservedWindow(aura::Window* window); + void RemoveAllObservedWindows(); + + private: + std::set observed_windows_; }; void WindowBoundsChangeObserver::OnWindowBoundsChanged(aura::Window* window, @@ -219,6 +227,21 @@ void WindowBoundsChangeObserver::OnWindowBoundsChanged(aura::Window* window, void WindowBoundsChangeObserver::OnWindowDestroyed(aura::Window* window) { if (window->HasObserver(this)) window->RemoveObserver(this); + observed_windows_.erase(window); +} + +void WindowBoundsChangeObserver::AddObservedWindow(aura::Window* window) { + if (!window->HasObserver(this)) { + window->AddObserver(this); + observed_windows_.insert(window); + } +} + +void WindowBoundsChangeObserver::RemoveAllObservedWindows() { + for (std::set::iterator it = observed_windows_.begin(); + it != observed_windows_.end(); ++it) + (*it)->RemoveObserver(this); + observed_windows_.clear(); } // static @@ -533,12 +556,10 @@ void KeyboardController::ResetWindowInsets() { content::RenderWidgetHost::GetRenderWidgetHosts()); while (content::RenderWidgetHost* widget = widgets->GetNextHost()) { content::RenderWidgetHostView* view = widget->GetView(); - if (view) { + if (view) view->SetInsets(insets); - aura::Window *window = view->GetNativeView(); - RemoveBoundsChangedObserver(window); - } } + window_bounds_observer_->RemoveAllObservedWindows(); } bool KeyboardController::WillHideKeyboard() const { @@ -558,18 +579,8 @@ void KeyboardController::HideAnimationFinished() { void KeyboardController::AddBoundsChangedObserver(aura::Window* window) { aura::Window* target_window = GetFrameWindow(window); - if (target_window && - !target_window->HasObserver(window_bounds_observer_.get())) { - target_window->AddObserver(window_bounds_observer_.get()); - } -} - -void KeyboardController::RemoveBoundsChangedObserver(aura::Window* window) { - aura::Window* target_window = GetFrameWindow(window); - if (target_window && - target_window->HasObserver(window_bounds_observer_.get())) { - target_window->RemoveObserver(window_bounds_observer_.get()); - } + if (target_window) + window_bounds_observer_->AddObservedWindow(target_window); } } // namespace keyboard diff --git a/ui/keyboard/keyboard_controller.h b/ui/keyboard/keyboard_controller.h index 492a0ca006509..55b67934af87d 100644 --- a/ui/keyboard/keyboard_controller.h +++ b/ui/keyboard/keyboard_controller.h @@ -139,11 +139,10 @@ class KEYBOARD_EXPORT KeyboardController : public ui::InputMethodObserver, void ShowAnimationFinished(); void HideAnimationFinished(); - // Adds or removes an observer for tracking changes to a window size or + // Adds an observer for tracking changes to a window size or // position while the keyboard is displayed. Any window repositioning // invalidates insets for overscrolling. void AddBoundsChangedObserver(aura::Window* window); - void RemoveBoundsChangedObserver(aura::Window* window); scoped_ptr proxy_; scoped_ptr container_;