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

Side by Side Diff: ui/views/corewm/window_animations.cc

Issue 150573007: Add check to determine if HidingWindowAnimationObserver is source of crbug.com/338788 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 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 | Annotate | Revision Log
« no previous file with comments | « chrome/common/crash_keys.cc ('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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "ui/views/corewm/window_animations.h" 5 #include "ui/views/corewm/window_animations.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <set>
10 #include <vector> 11 #include <vector>
11 12
12 #include "base/command_line.h" 13 #include "base/command_line.h"
13 #include "base/compiler_specific.h" 14 #include "base/compiler_specific.h"
15 #include "base/debug/crash_logging.h"
14 #include "base/logging.h" 16 #include "base/logging.h"
15 #include "base/message_loop/message_loop.h" 17 #include "base/message_loop/message_loop.h"
16 #include "base/stl_util.h" 18 #include "base/stl_util.h"
17 #include "base/time/time.h" 19 #include "base/time/time.h"
18 #include "ui/aura/client/animation_host.h" 20 #include "ui/aura/client/animation_host.h"
19 #include "ui/aura/client/aura_constants.h" 21 #include "ui/aura/client/aura_constants.h"
20 #include "ui/aura/window.h" 22 #include "ui/aura/window.h"
21 #include "ui/aura/window_delegate.h" 23 #include "ui/aura/window_delegate.h"
22 #include "ui/aura/window_observer.h" 24 #include "ui/aura/window_observer.h"
23 #include "ui/aura/window_property.h" 25 #include "ui/aura/window_property.h"
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 // destroyed when the stack unwinds. To handle this case, we start the hide 120 // destroyed when the stack unwinds. To handle this case, we start the hide
119 // animation immediately when the window is hidden, then when the window is 121 // animation immediately when the window is hidden, then when the window is
120 // subsequently destroyed this object acquires ownership of the window's layer, 122 // subsequently destroyed this object acquires ownership of the window's layer,
121 // so that it can continue animating it until the animation completes. 123 // so that it can continue animating it until the animation completes.
122 // Regardless of whether or not the window is destroyed, this object deletes 124 // Regardless of whether or not the window is destroyed, this object deletes
123 // itself when the animation completes. 125 // itself when the animation completes.
124 class HidingWindowAnimationObserver : public ui::ImplicitAnimationObserver, 126 class HidingWindowAnimationObserver : public ui::ImplicitAnimationObserver,
125 public aura::WindowObserver { 127 public aura::WindowObserver {
126 public: 128 public:
127 explicit HidingWindowAnimationObserver(aura::Window* window) 129 explicit HidingWindowAnimationObserver(aura::Window* window)
128 : window_(window) { 130 : topmost_window_(window) {
129 window_->AddObserver(this); 131 topmost_window_->AddObserver(this);
132 observed_.insert(topmost_window_);
130 } 133 }
131 virtual ~HidingWindowAnimationObserver() { 134 virtual ~HidingWindowAnimationObserver() {
132 STLDeleteElements(&layers_); 135 STLDeleteElements(&layers_);
136
137 #if defined(OS_CHROMEOS)
138 // |topmost_window_| should either be not destroyed or |topmost_window_|
139 // and all of its children should be destroyed.
140 // TODO(pkotwicz): Remove CHECK once it has been determined whether a child
141 // window outliving the end of |topmost_window_|'s animation is the source
142 // of the crash in crbug.com/338788
143 if (!topmost_window_ && !observed_.empty()) {
144 aura::Window* first_observed = *observed_.begin();
145 std::string name = first_observed->name();
146 base::debug::SetCrashKeyValue("window_destroyed_layer", name);
147 CHECK(false);
148 }
149 #endif // defined(OS_CHROMEOS)
150
151 for (std::set<aura::Window*>::const_iterator it = observed_.begin();
152 it != observed_.end();
153 ++it) {
154 (*it)->RemoveObserver(this);
155 }
133 } 156 }
134 157
135 private: 158 private:
136 // Overridden from ui::ImplicitAnimationObserver: 159 // Overridden from ui::ImplicitAnimationObserver:
137 virtual void OnImplicitAnimationsCompleted() OVERRIDE { 160 virtual void OnImplicitAnimationsCompleted() OVERRIDE {
138 // Window may have been destroyed by this point. 161 // Window may have been destroyed by this point.
139 if (window_) { 162 if (topmost_window_) {
140 aura::client::AnimationHost* animation_host = 163 aura::client::AnimationHost* animation_host =
141 aura::client::GetAnimationHost(window_); 164 aura::client::GetAnimationHost(topmost_window_);
142 if (animation_host) 165 if (animation_host)
143 animation_host->OnWindowHidingAnimationCompleted(); 166 animation_host->OnWindowHidingAnimationCompleted();
144 window_->RemoveObserver(this);
145 } 167 }
146 delete this; 168 delete this;
147 } 169 }
148 170
149 // Overridden from aura::WindowObserver: 171 // Overridden from aura::WindowObserver:
150 virtual void OnWindowDestroying(aura::Window* window) OVERRIDE { 172 virtual void OnWindowDestroying(aura::Window* window) OVERRIDE {
151 DCHECK_EQ(window, window_); 173 window->RemoveObserver(this);
174 observed_.erase(window);
175
176 if (window != topmost_window_)
177 return;
178
179 // We acquire the layers of all of |topmost_window_|'s children with the
180 // assumption that they will be destroyed by the time that the animation
181 // terminates. Observe |topmost_window_|'s children to verify the
182 // assumption.
183 ObserveAllChildren(topmost_window_);
184
152 DCHECK(layers_.empty()); 185 DCHECK(layers_.empty());
153 AcquireAllLayers(window_); 186 AcquireAllLayers(topmost_window_);
154 187
155 // If the Widget has views with layers, then it is necessary to take 188 // If the Widget has views with layers, then it is necessary to take
156 // ownership of those layers too. 189 // ownership of those layers too.
157 views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window_); 190 views::Widget* widget = views::Widget::GetWidgetForNativeWindow(
191 topmost_window_);
158 const views::Widget* const_widget = widget; 192 const views::Widget* const_widget = widget;
159 if (widget && const_widget->GetRootView() && widget->GetContentsView()) 193 if (widget && const_widget->GetRootView() && widget->GetContentsView())
160 AcquireAllViewLayers(widget->GetContentsView()); 194 AcquireAllViewLayers(widget->GetContentsView());
161 window_->RemoveObserver(this); 195 topmost_window_ = NULL;
162 window_ = NULL; 196 }
197
198 // Starts observing all of the windows in a subtree rooted at |window|
199 // excluding |window|.
200 void ObserveAllChildren(aura::Window* window) {
201 for (aura::Window::Windows::const_iterator it = window->children().begin();
202 it != window->children().end();
203 ++it) {
204 aura::Window* child = *it;
205 child->AddObserver(this);
206 observed_.insert(child);
207 ObserveAllChildren(child);
208 }
163 } 209 }
164 210
165 void AcquireAllLayers(aura::Window* window) { 211 void AcquireAllLayers(aura::Window* window) {
166 ui::Layer* layer = window->AcquireLayer(); 212 ui::Layer* layer = window->AcquireLayer();
167 DCHECK(layer); 213 DCHECK(layer);
168 layers_.push_back(layer); 214 layers_.push_back(layer);
169 for (aura::Window::Windows::const_iterator it = window->children().begin(); 215 for (aura::Window::Windows::const_iterator it = window->children().begin();
170 it != window->children().end(); 216 it != window->children().end();
171 ++it) 217 ++it)
172 AcquireAllLayers(*it); 218 AcquireAllLayers(*it);
173 } 219 }
174 220
175 void AcquireAllViewLayers(views::View* view) { 221 void AcquireAllViewLayers(views::View* view) {
176 for (int i = 0; i < view->child_count(); ++i) 222 for (int i = 0; i < view->child_count(); ++i)
177 AcquireAllViewLayers(view->child_at(i)); 223 AcquireAllViewLayers(view->child_at(i));
178 if (view->layer()) { 224 if (view->layer()) {
179 ui::Layer* layer = view->RecreateLayer(); 225 ui::Layer* layer = view->RecreateLayer();
180 if (layer) { 226 if (layer) {
181 layer->SuppressPaint(); 227 layer->SuppressPaint();
182 layers_.push_back(layer); 228 layers_.push_back(layer);
183 } 229 }
184 } 230 }
185 } 231 }
186 232
187 aura::Window* window_; 233 aura::Window* topmost_window_;
234
235 // The set of windows observed by this class.
236 std::set<aura::Window*> observed_;
237
188 std::vector<ui::Layer*> layers_; 238 std::vector<ui::Layer*> layers_;
189 239
190 DISALLOW_COPY_AND_ASSIGN(HidingWindowAnimationObserver); 240 DISALLOW_COPY_AND_ASSIGN(HidingWindowAnimationObserver);
191 }; 241 };
192 242
193 void GetTransformRelativeToRoot(ui::Layer* layer, gfx::Transform* transform) { 243 void GetTransformRelativeToRoot(ui::Layer* layer, gfx::Transform* transform) {
194 const Layer* root = layer; 244 const Layer* root = layer;
195 while (root->parent()) 245 while (root->parent())
196 root = root->parent(); 246 root = root->parent();
197 layer->GetTargetTransformRelativeTo(root, transform); 247 layer->GetTargetTransformRelativeTo(root, transform);
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
569 619
570 bool WindowAnimationsDisabled(aura::Window* window) { 620 bool WindowAnimationsDisabled(aura::Window* window) {
571 return (!gfx::Animation::ShouldRenderRichAnimation() || (window && 621 return (!gfx::Animation::ShouldRenderRichAnimation() || (window &&
572 window->GetProperty(aura::client::kAnimationsDisabledKey)) || 622 window->GetProperty(aura::client::kAnimationsDisabledKey)) ||
573 CommandLine::ForCurrentProcess()->HasSwitch( 623 CommandLine::ForCurrentProcess()->HasSwitch(
574 switches::kWindowAnimationsDisabled)); 624 switches::kWindowAnimationsDisabled));
575 } 625 }
576 626
577 } // namespace corewm 627 } // namespace corewm
578 } // namespace views 628 } // namespace views
OLDNEW
« no previous file with comments | « chrome/common/crash_keys.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698