Index: trunk/src/chrome/browser/ui/startup/session_crashed_infobar_delegate.cc |
=================================================================== |
--- trunk/src/chrome/browser/ui/startup/session_crashed_infobar_delegate.cc (revision 238401) |
+++ trunk/src/chrome/browser/ui/startup/session_crashed_infobar_delegate.cc (working copy) |
@@ -4,6 +4,7 @@ |
#include "chrome/browser/ui/startup/session_crashed_infobar_delegate.h" |
+#include "chrome/browser/chrome_notification_types.h" |
#include "chrome/browser/infobars/infobar.h" |
#include "chrome/browser/profiles/profile.h" |
#include "chrome/browser/search/search.h" |
@@ -13,6 +14,7 @@ |
#include "chrome/browser/ui/tabs/tab_strip_model.h" |
#include "chrome/common/url_constants.h" |
#include "content/public/browser/dom_storage_context.h" |
+#include "content/public/browser/notification_service.h" |
#include "content/public/browser/storage_partition.h" |
#include "grit/chromium_strings.h" |
#include "grit/generated_resources.h" |
@@ -32,21 +34,31 @@ |
if (profile->IsOffTheRecord() || !web_contents) |
return; |
- InfoBarService::FromWebContents(web_contents)->AddInfoBar( |
- ConfirmInfoBarDelegate::CreateInfoBar(scoped_ptr<ConfirmInfoBarDelegate>( |
- new SessionCrashedInfoBarDelegate(profile)))); |
+ InfoBarService* infobar_service = |
+ InfoBarService::FromWebContents(web_contents); |
+ infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>( |
+ new SessionCrashedInfoBarDelegate(infobar_service, profile))); |
} |
-SessionCrashedInfoBarDelegate::SessionCrashedInfoBarDelegate(Profile* profile) |
- : ConfirmInfoBarDelegate(), |
+SessionCrashedInfoBarDelegate::SessionCrashedInfoBarDelegate( |
+ InfoBarService* infobar_service, |
+ Profile* profile) |
+ : ConfirmInfoBarDelegate(infobar_service), |
accepted_(false), |
+ removed_notification_received_(false), |
profile_(profile) { |
+ // TODO(pkasting,marja): Once InfoBars own they delegates, this is not needed |
+ // any more. Then we can rely on delegates getting destroyed, and we can |
+ // initiate the session storage scavenging only in the destructor. (Currently, |
+ // info bars are leaked if they get closed while they're in background tabs.) |
+ registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, |
+ content::NotificationService::AllSources()); |
} |
SessionCrashedInfoBarDelegate::~SessionCrashedInfoBarDelegate() { |
// If the info bar wasn't accepted, it was either dismissed or expired. In |
// that case, session restore won't happen. |
- if (!accepted_) { |
+ if (!accepted_ && !removed_notification_received_) { |
content::BrowserContext::GetDefaultStoragePartition(profile_)-> |
GetDOMStorageContext()->StartScavengingUnusedSessionStorage(); |
} |
@@ -72,7 +84,8 @@ |
bool SessionCrashedInfoBarDelegate::Accept() { |
uint32 behavior = 0; |
- Browser* browser = chrome::FindBrowserWithWebContents(web_contents()); |
+ Browser* browser = |
+ chrome::FindBrowserWithWebContents(owner()->web_contents()); |
if (browser->tab_strip_model()->count() == 1) { |
const content::WebContents* active_tab = |
browser->tab_strip_model()->GetWebContentsAt(0); |
@@ -89,3 +102,17 @@ |
accepted_ = true; |
return true; |
} |
+ |
+void SessionCrashedInfoBarDelegate::Observe( |
+ int type, |
+ const content::NotificationSource& source, |
+ const content::NotificationDetails& details) { |
+ DCHECK(type == chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED); |
+ if (content::Details<InfoBar::RemovedDetails>(details)->first != this) |
+ return; |
+ if (!accepted_) { |
+ content::BrowserContext::GetDefaultStoragePartition(profile_)-> |
+ GetDOMStorageContext()->StartScavengingUnusedSessionStorage(); |
+ removed_notification_received_ = true; |
+ } |
+} |