Index: trunk/src/chrome/browser/infobars/infobar.cc |
=================================================================== |
--- trunk/src/chrome/browser/infobars/infobar.cc (revision 238401) |
+++ trunk/src/chrome/browser/infobars/infobar.cc (working copy) |
@@ -12,9 +12,9 @@ |
#include "chrome/browser/infobars/infobar_service.h" |
#include "ui/gfx/animation/slide_animation.h" |
-InfoBar::InfoBar(scoped_ptr<InfoBarDelegate> delegate) |
- : owner_(NULL), |
- delegate_(delegate.Pass()), |
+InfoBar::InfoBar(InfoBarService* owner, InfoBarDelegate* delegate) |
+ : owner_(owner), |
+ delegate_(delegate), |
container_(NULL), |
animation_(this), |
arrow_height_(0), |
@@ -22,13 +22,12 @@ |
arrow_half_width_(0), |
bar_height_(0), |
bar_target_height_(kDefaultBarTargetHeight) { |
+ DCHECK(owner_ != NULL); |
DCHECK(delegate_ != NULL); |
animation_.SetTweenType(gfx::Tween::LINEAR); |
- delegate_->set_infobar(this); |
} |
InfoBar::~InfoBar() { |
- DCHECK(!owner_); |
} |
// static |
@@ -51,13 +50,6 @@ |
kWarningBackgroundColorBottom : kPageActionBackgroundColorBottom; |
} |
-void InfoBar::SetOwner(InfoBarService* owner) { |
- DCHECK(!owner_); |
- owner_ = owner; |
- delegate_->StoreActiveEntryUniqueID(); |
- PlatformSpecificSetOwner(); |
-} |
- |
void InfoBar::Show(bool animate) { |
PlatformSpecificShow(animate); |
if (animate) { |
@@ -98,11 +90,6 @@ |
MaybeDelete(); |
} |
-void InfoBar::RemoveSelf() { |
- if (owner_) |
- owner_->RemoveInfoBar(this); |
-} |
- |
void InfoBar::SetBarTargetHeight(int height) { |
if (bar_target_height_ != height) { |
bar_target_height_ = height; |
@@ -114,6 +101,19 @@ |
RecalculateHeights(false); |
} |
+void InfoBar::RemoveSelf() { |
+ // |owner_| should never be NULL here. If it is, then someone violated what |
+ // they were supposed to do -- e.g. a ConfirmInfoBarDelegate subclass returned |
+ // true from Accept() or Cancel() even though the infobar was already closing. |
+ // In the worst case, if we also switched tabs during that process, then |
+ // |this| has already been destroyed. But if that's the case, then we're |
+ // going to deref a garbage |this| pointer here whether we check |owner_| or |
+ // not, and in other cases (where we're still closing and |this| is valid), |
+ // checking |owner_| here will avoid a NULL deref. |
+ if (owner_) |
+ owner_->RemoveInfoBar(delegate_); |
+} |
+ |
int InfoBar::OffsetY(const gfx::Size& prefsize) const { |
return arrow_height_ + |
std::max((bar_target_height_ - prefsize.height()) / 2, 0) - |
@@ -173,9 +173,10 @@ |
} |
void InfoBar::MaybeDelete() { |
- if (!owner_ && (animation_.GetCurrentValue() == 0.0)) { |
+ if (!owner_ && delegate_ && (animation_.GetCurrentValue() == 0.0)) { |
if (container_) |
container_->RemoveInfoBar(this); |
- delete this; |
+ delete delegate_; |
+ delegate_ = NULL; |
} |
} |