Commit ab56fb3a authored by paul@chromium.org's avatar paul@chromium.org

Fix a crash when closing an incognito window with a download

shelf visible.

We explicitly remove the download shelf view from the browser
view hierarchy during a window close operation. This avoids
calling back into the partially deleted view hierarchy with
download deleted observer notifications. Explicitly removing
the shelf allows the observer notifications to run first while
the views are still valid.


To reproduce:
1. Launch Chrome
2. Open an incognito window
3. Download something in the incognito window
4. The download shelf should become visible with one entry
5. Close the incognito window
6. Crash

BUG=13681 (http://crbug.com/13681)

Review URL: http://codereview.chromium.org/126082

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18458 0039d316-1c4b-4281-b951-d872f2087c98
parent 5214f719
...@@ -274,7 +274,6 @@ BrowserView::BrowserView(Browser* browser) ...@@ -274,7 +274,6 @@ BrowserView::BrowserView(Browser* browser)
active_bookmark_bar_(NULL), active_bookmark_bar_(NULL),
tabstrip_(NULL), tabstrip_(NULL),
toolbar_(NULL), toolbar_(NULL),
download_shelf_(NULL),
infobar_container_(NULL), infobar_container_(NULL),
find_bar_y_(0), find_bar_y_(0),
contents_container_(NULL), contents_container_(NULL),
...@@ -298,6 +297,12 @@ BrowserView::~BrowserView() { ...@@ -298,6 +297,12 @@ BrowserView::~BrowserView() {
ticker_.UnregisterTickHandler(&hung_window_detector_); ticker_.UnregisterTickHandler(&hung_window_detector_);
#endif #endif
// We destroy the download shelf before |browser_| to remove its child
// download views from the set of download observers (since the observed
// downloads can be destroyed along with |browser_| and the observer
// notifications will call back into deleted objects).
download_shelf_.reset();
// Explicitly set browser_ to NULL // Explicitly set browser_ to NULL
browser_.reset(); browser_.reset();
} }
...@@ -787,7 +792,7 @@ gfx::Rect BrowserView::GetRootWindowResizerRect() const { ...@@ -787,7 +792,7 @@ gfx::Rect BrowserView::GetRootWindowResizerRect() const {
// shelf, so we don't want others to do it for us in this case. // shelf, so we don't want others to do it for us in this case.
// Currently, the only visible bottom shelf is the download shelf. // Currently, the only visible bottom shelf is the download shelf.
// Other tests should be added here if we add more bottom shelves. // Other tests should be added here if we add more bottom shelves.
if (download_shelf_ && download_shelf_->IsShowing()) { if (download_shelf_.get() && download_shelf_->IsShowing()) {
return gfx::Rect(); return gfx::Rect();
} }
...@@ -842,13 +847,15 @@ void BrowserView::SetDownloadShelfVisible(bool visible) { ...@@ -842,13 +847,15 @@ void BrowserView::SetDownloadShelfVisible(bool visible) {
} }
bool BrowserView::IsDownloadShelfVisible() const { bool BrowserView::IsDownloadShelfVisible() const {
return download_shelf_ && download_shelf_->IsShowing(); return download_shelf_.get() && download_shelf_->IsShowing();
} }
DownloadShelf* BrowserView::GetDownloadShelf() { DownloadShelf* BrowserView::GetDownloadShelf() {
if (!download_shelf_) if (!download_shelf_.get()) {
download_shelf_ = new DownloadShelfView(browser_.get(), this); download_shelf_.reset(new DownloadShelfView(browser_.get(), this));
return download_shelf_; download_shelf_->SetParentOwned(false);
}
return download_shelf_.get();
} }
void BrowserView::ShowReportBugDialog() { void BrowserView::ShowReportBugDialog() {
...@@ -1493,7 +1500,7 @@ int BrowserView::LayoutDownloadShelf(int bottom) { ...@@ -1493,7 +1500,7 @@ int BrowserView::LayoutDownloadShelf(int bottom) {
if (IsDownloadShelfVisible()) { if (IsDownloadShelfVisible()) {
bool visible = browser_->SupportsWindowFeature( bool visible = browser_->SupportsWindowFeature(
Browser::FEATURE_DOWNLOADSHELF); Browser::FEATURE_DOWNLOADSHELF);
DCHECK(download_shelf_); DCHECK(download_shelf_.get());
int height = visible ? download_shelf_->GetPreferredSize().height() : 0; int height = visible ? download_shelf_->GetPreferredSize().height() : 0;
download_shelf_->SetVisible(visible); download_shelf_->SetVisible(visible);
download_shelf_->SetBounds(0, bottom - height, width(), height); download_shelf_->SetBounds(0, bottom - height, width(), height);
......
...@@ -391,7 +391,7 @@ class BrowserView : public BrowserWindow, ...@@ -391,7 +391,7 @@ class BrowserView : public BrowserWindow,
scoped_ptr<BookmarkBarView> bookmark_bar_view_; scoped_ptr<BookmarkBarView> bookmark_bar_view_;
// The download shelf view (view at the bottom of the page). // The download shelf view (view at the bottom of the page).
DownloadShelfView* download_shelf_; scoped_ptr<DownloadShelfView> download_shelf_;
// The InfoBarContainer that contains InfoBars for the current tab. // The InfoBarContainer that contains InfoBars for the current tab.
InfoBarContainer* infobar_container_; InfoBarContainer* infobar_container_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment