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

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 | « no previous file | 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"
14 #include "base/logging.h" 15 #include "base/logging.h"
15 #include "base/message_loop/message_loop.h" 16 #include "base/message_loop/message_loop.h"
16 #include "base/stl_util.h" 17 #include "base/stl_util.h"
17 #include "base/time/time.h" 18 #include "base/time/time.h"
18 #include "ui/aura/client/animation_host.h" 19 #include "ui/aura/client/animation_host.h"
19 #include "ui/aura/client/aura_constants.h" 20 #include "ui/aura/client/aura_constants.h"
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 // destroyed when the stack unwinds. To handle this case, we start the hide 119 // 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 120 // animation immediately when the window is hidden, then when the window is
120 // subsequently destroyed this object acquires ownership of the window's layer, 121 // subsequently destroyed this object acquires ownership of the window's layer,
121 // so that it can continue animating it until the animation completes. 122 // so that it can continue animating it until the animation completes.
122 // Regardless of whether or not the window is destroyed, this object deletes 123 // Regardless of whether or not the window is destroyed, this object deletes
123 // itself when the animation completes. 124 // itself when the animation completes.
124 class HidingWindowAnimationObserver : public ui::ImplicitAnimationObserver, 125 class HidingWindowAnimationObserver : public ui::ImplicitAnimationObserver,
125 public aura::WindowObserver { 126 public aura::WindowObserver {
126 public: 127 public:
127 explicit HidingWindowAnimationObserver(aura::Window* window) 128 explicit HidingWindowAnimationObserver(aura::Window* window)
128 : window_(window) { 129 : topmost_window_(window) {
129 window_->AddObserver(this); 130 topmost_window_->AddObserver(this);
131 observed_.insert(topmost_window_);
130 } 132 }
131 virtual ~HidingWindowAnimationObserver() { 133 virtual ~HidingWindowAnimationObserver() {
132 STLDeleteElements(&layers_); 134 STLDeleteElements(&layers_);
135
136 // |topmost_window_| should either be not destroyed or |topmost_window_|
137 // and all of its children should be destroyed.
138 // TODO(pkotwicz): Remove CHECK once it has been determined whether a child
139 // window outliving the end of |topmost_window_|'s animation is the source
140 // of the crash in crbug.com/338788
141 CHECK(topmost_window_ || observed_.empty());
sky 2014/02/05 21:38:15 If observed_ is not empty, is it possible to embed
142
143 for (std::set<aura::Window*>::const_iterator it = observed_.begin();
144 it != observed_.end();
145 ++it) {
146 (*it)->RemoveObserver(this);
147 }
133 } 148 }
134 149
135 private: 150 private:
136 // Overridden from ui::ImplicitAnimationObserver: 151 // Overridden from ui::ImplicitAnimationObserver:
137 virtual void OnImplicitAnimationsCompleted() OVERRIDE { 152 virtual void OnImplicitAnimationsCompleted() OVERRIDE {
138 // Window may have been destroyed by this point. 153 // Window may have been destroyed by this point.
139 if (window_) { 154 if (topmost_window_) {
140 aura::client::AnimationHost* animation_host = 155 aura::client::AnimationHost* animation_host =
141 aura::client::GetAnimationHost(window_); 156 aura::client::GetAnimationHost(topmost_window_);
142 if (animation_host) 157 if (animation_host)
143 animation_host->OnWindowHidingAnimationCompleted(); 158 animation_host->OnWindowHidingAnimationCompleted();
144 window_->RemoveObserver(this);
145 } 159 }
146 delete this; 160 delete this;
147 } 161 }
148 162
149 // Overridden from aura::WindowObserver: 163 // Overridden from aura::WindowObserver:
150 virtual void OnWindowDestroying(aura::Window* window) OVERRIDE { 164 virtual void OnWindowDestroying(aura::Window* window) OVERRIDE {
151 DCHECK_EQ(window, window_); 165 window->RemoveObserver(this);
166 observed_.erase(window);
167
168 if (window != topmost_window_)
169 return;
170
171 // We acquire the layers of all of |topmost_window_|'s children with the
172 // assumption that they will be destroyed by the time that the animation
173 // terminates. Observe |topmost_window_|'s children to verify the
174 // assumption.
175 ObserveAllChildren(topmost_window_);
176
152 DCHECK(layers_.empty()); 177 DCHECK(layers_.empty());
153 AcquireAllLayers(window_); 178 AcquireAllLayers(topmost_window_);
154 179
155 // If the Widget has views with layers, then it is necessary to take 180 // If the Widget has views with layers, then it is necessary to take
156 // ownership of those layers too. 181 // ownership of those layers too.
157 views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window_); 182 views::Widget* widget = views::Widget::GetWidgetForNativeWindow(
183 topmost_window_);
158 const views::Widget* const_widget = widget; 184 const views::Widget* const_widget = widget;
159 if (widget && const_widget->GetRootView() && widget->GetContentsView()) 185 if (widget && const_widget->GetRootView() && widget->GetContentsView())
160 AcquireAllViewLayers(widget->GetContentsView()); 186 AcquireAllViewLayers(widget->GetContentsView());
161 window_->RemoveObserver(this); 187 topmost_window_ = NULL;
162 window_ = NULL; 188 }
189
190 // Starts observing all of the windows in a subtree rooted at |window|
191 // excluding |window|.
192 void ObserveAllChildren(aura::Window* window) {
193 for (aura::Window::Windows::const_iterator it = window->children().begin();
194 it != window->children().end();
195 ++it) {
196 aura::Window* child = *it;
197 child->AddObserver(this);
198 observed_.insert(child);
199 ObserveAllChildren(child);
200 }
163 } 201 }
164 202
165 void AcquireAllLayers(aura::Window* window) { 203 void AcquireAllLayers(aura::Window* window) {
166 ui::Layer* layer = window->AcquireLayer(); 204 ui::Layer* layer = window->AcquireLayer();
167 DCHECK(layer); 205 DCHECK(layer);
168 layers_.push_back(layer); 206 layers_.push_back(layer);
169 for (aura::Window::Windows::const_iterator it = window->children().begin(); 207 for (aura::Window::Windows::const_iterator it = window->children().begin();
170 it != window->children().end(); 208 it != window->children().end();
171 ++it) 209 ++it)
172 AcquireAllLayers(*it); 210 AcquireAllLayers(*it);
173 } 211 }
174 212
175 void AcquireAllViewLayers(views::View* view) { 213 void AcquireAllViewLayers(views::View* view) {
176 for (int i = 0; i < view->child_count(); ++i) 214 for (int i = 0; i < view->child_count(); ++i)
177 AcquireAllViewLayers(view->child_at(i)); 215 AcquireAllViewLayers(view->child_at(i));
178 if (view->layer()) { 216 if (view->layer()) {
179 ui::Layer* layer = view->RecreateLayer(); 217 ui::Layer* layer = view->RecreateLayer();
180 if (layer) { 218 if (layer) {
181 layer->SuppressPaint(); 219 layer->SuppressPaint();
182 layers_.push_back(layer); 220 layers_.push_back(layer);
183 } 221 }
184 } 222 }
185 } 223 }
186 224
187 aura::Window* window_; 225 aura::Window* topmost_window_;
226
227 // The set of windows observed by this class.
228 std::set<aura::Window*> observed_;
229
188 std::vector<ui::Layer*> layers_; 230 std::vector<ui::Layer*> layers_;
189 231
190 DISALLOW_COPY_AND_ASSIGN(HidingWindowAnimationObserver); 232 DISALLOW_COPY_AND_ASSIGN(HidingWindowAnimationObserver);
191 }; 233 };
192 234
193 void GetTransformRelativeToRoot(ui::Layer* layer, gfx::Transform* transform) { 235 void GetTransformRelativeToRoot(ui::Layer* layer, gfx::Transform* transform) {
194 const Layer* root = layer; 236 const Layer* root = layer;
195 while (root->parent()) 237 while (root->parent())
196 root = root->parent(); 238 root = root->parent();
197 layer->GetTargetTransformRelativeTo(root, transform); 239 layer->GetTargetTransformRelativeTo(root, transform);
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
569 611
570 bool WindowAnimationsDisabled(aura::Window* window) { 612 bool WindowAnimationsDisabled(aura::Window* window) {
571 return (!gfx::Animation::ShouldRenderRichAnimation() || (window && 613 return (!gfx::Animation::ShouldRenderRichAnimation() || (window &&
572 window->GetProperty(aura::client::kAnimationsDisabledKey)) || 614 window->GetProperty(aura::client::kAnimationsDisabledKey)) ||
573 CommandLine::ForCurrentProcess()->HasSwitch( 615 CommandLine::ForCurrentProcess()->HasSwitch(
574 switches::kWindowAnimationsDisabled)); 616 switches::kWindowAnimationsDisabled));
575 } 617 }
576 618
577 } // namespace corewm 619 } // namespace corewm
578 } // namespace views 620 } // namespace views
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698