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

Side by Side Diff: chrome/common/extensions/extension_action.cc

Issue 10823142: Fix a race condition when an IconAnimation is still running at browser shutdown. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Comment tweak. Created 8 years, 4 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
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 "chrome/common/extensions/extension_action.h" 5 #include "chrome/common/extensions/extension_action.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "chrome/common/badge_util.h" 10 #include "chrome/common/badge_util.h"
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 54
55 55
56 int Width(const gfx::Image& image) { 56 int Width(const gfx::Image& image) {
57 if (image.IsEmpty()) 57 if (image.IsEmpty())
58 return 0; 58 return 0;
59 return image.ToSkBitmap()->width(); 59 return image.ToSkBitmap()->width();
60 } 60 }
61 61
62 } // namespace 62 } // namespace
63 63
64 // Wraps an IconAnimation and implements its ui::AnimationDelegate to erase the 64 // Wraps an IconAnimation and implements its ui::AnimationDelegate to delete
65 // animation from a map when the animation ends or is cancelled, causing itself 65 // itself when the animation ends or is cancelled, causing its owned
66 // and its owned IconAnimation to be deleted. 66 // IconAnimation to be destroyed.
67 class ExtensionAction::IconAnimationWrapper : public ui::AnimationDelegate { 67 class ExtensionAction::IconAnimationWrapper
68 : public ui::AnimationDelegate,
69 public base::SupportsWeakPtr<IconAnimationWrapper> {
68 public: 70 public:
69 IconAnimationWrapper(ExtensionAction* owner, int tab_id) 71 IconAnimationWrapper()
70 : owner_(owner), 72 : ALLOW_THIS_IN_INITIALIZER_LIST(animation_(this)) {}
71 tab_id_(tab_id),
72 ALLOW_THIS_IN_INITIALIZER_LIST(animation_(this)) {}
73 73
74 virtual ~IconAnimationWrapper() {} 74 virtual ~IconAnimationWrapper() {}
75 75
76 IconAnimation* animation() { 76 IconAnimation* animation() {
77 return &animation_; 77 return &animation_;
78 } 78 }
79 79
80 private: 80 private:
81 virtual void AnimationEnded(const ui::Animation* animation) OVERRIDE { 81 virtual void AnimationEnded(const ui::Animation* animation) OVERRIDE {
82 Done(); 82 Done();
83 } 83 }
84 84
85 virtual void AnimationCanceled(const ui::Animation* animation) OVERRIDE { 85 virtual void AnimationCanceled(const ui::Animation* animation) OVERRIDE {
86 Done(); 86 Done();
87 } 87 }
88 88
89 void Done() { 89 void Done() {
90 owner_->icon_animation_.erase(tab_id_); 90 delete this;
91 // this will now have been deleted.
92 } 91 }
93 92
94 ExtensionAction* owner_;
95 int tab_id_;
96 IconAnimation animation_; 93 IconAnimation animation_;
97 }; 94 };
98 95
99 const int ExtensionAction::kDefaultTabId = -1; 96 const int ExtensionAction::kDefaultTabId = -1;
100 97
101 ExtensionAction::IconAnimation::IconAnimation( 98 ExtensionAction::IconAnimation::IconAnimation(
102 ui::AnimationDelegate* delegate) 99 ui::AnimationDelegate* delegate)
103 // 100ms animation at 50fps (so 5 animation frames in total). 100 // 100ms animation at 50fps (so 5 animation frames in total).
104 : ui::LinearAnimation(100, 50, delegate) {} 101 : ui::LinearAnimation(100, 50, delegate) {}
105 102
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 rect.fLeft += kPadding; 334 rect.fLeft += kPadding;
338 rect.fRight -= kPadding; 335 rect.fRight -= kPadding;
339 canvas->sk_canvas()->clipRect(rect); 336 canvas->sk_canvas()->clipRect(rect);
340 canvas->sk_canvas()->drawText(text.c_str(), text.size(), 337 canvas->sk_canvas()->drawText(text.c_str(), text.size(),
341 rect.fLeft + (rect.width() - text_width) / 2, 338 rect.fLeft + (rect.width() - text_width) / 2,
342 rect.fTop + kTextSize + kTopTextPadding, 339 rect.fTop + kTextSize + kTopTextPadding,
343 *text_paint); 340 *text_paint);
344 canvas->Restore(); 341 canvas->Restore();
345 } 342 }
346 343
344 ExtensionAction::IconAnimationWrapper* ExtensionAction::GetIconAnimationWrapper(
345 int tab_id) const {
346 std::map<int, base::WeakPtr<IconAnimationWrapper> >::iterator it =
347 icon_animation_.find(tab_id);
348 if (it == icon_animation_.end())
349 return NULL;
350 if (it->second)
351 return it->second;
352
353 // Take this opportunity to remove all the NULL IconAnimationWrappers from
354 // icon_animation_.
355 icon_animation_.erase(it);
356 for (std::map<int, base::WeakPtr<IconAnimationWrapper> >::iterator it =
357 icon_animation_.begin(); it != icon_animation_.end();) {
not at google - send to devlin 2012/08/02 14:44:25 nits: you could re-use the iterator? saves some t
Jeffrey Yasskin 2012/08/02 15:11:49 Sure.
358 if (it->second) {
359 ++it;
360 } else {
361 // The WeakPtr is null; remove it from the map.
362 icon_animation_.erase(it++);
363 }
364 }
365 return NULL;
366 }
367
347 base::WeakPtr<ExtensionAction::IconAnimation> ExtensionAction::GetIconAnimation( 368 base::WeakPtr<ExtensionAction::IconAnimation> ExtensionAction::GetIconAnimation(
348 int tab_id) const { 369 int tab_id) const {
349 std::map<int, linked_ptr<IconAnimationWrapper> >::const_iterator it = 370 IconAnimationWrapper* wrapper = GetIconAnimationWrapper(tab_id);
350 icon_animation_.find(tab_id); 371 return wrapper ? wrapper->animation()->AsWeakPtr()
351 return (it != icon_animation_.end()) ? it->second->animation()->AsWeakPtr() 372 : base::WeakPtr<IconAnimation>();
352 : base::WeakPtr<IconAnimation>();
353 } 373 }
354 374
355 gfx::Image ExtensionAction::ApplyIconAnimation(int tab_id, 375 gfx::Image ExtensionAction::ApplyIconAnimation(int tab_id,
356 const gfx::Image& orig) const { 376 const gfx::Image& orig) const {
357 std::map<int, linked_ptr<IconAnimationWrapper> >::const_iterator it = 377 IconAnimationWrapper* wrapper = GetIconAnimationWrapper(tab_id);
358 icon_animation_.find(tab_id); 378 if (wrapper == NULL)
359 if (it == icon_animation_.end())
360 return orig; 379 return orig;
361 return gfx::Image(it->second->animation()->Apply(*orig.ToSkBitmap())); 380 return gfx::Image(wrapper->animation()->Apply(*orig.ToSkBitmap()));
362 } 381 }
363 382
364 void ExtensionAction::RunIconAnimation(int tab_id) { 383 void ExtensionAction::RunIconAnimation(int tab_id) {
365 IconAnimationWrapper* icon_animation = 384 IconAnimationWrapper* icon_animation =
366 new IconAnimationWrapper(this, tab_id); 385 new IconAnimationWrapper();
367 icon_animation_[tab_id] = make_linked_ptr(icon_animation); 386 icon_animation_[tab_id] = icon_animation->AsWeakPtr();
368 icon_animation->animation()->Start(); 387 icon_animation->animation()->Start();
369 } 388 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698