diff options
author | pkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-31 23:54:19 +0000 |
---|---|---|
committer | pkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-31 23:54:19 +0000 |
commit | 4421b8c0cdcda67bfbdca6b75d44aef5e204e860 (patch) | |
tree | afb22f52b005b8ca6582a08038a41418c0bb7b12 | |
parent | 88feaca65d66932c73847d7150cf9a7d91f7069d (diff) | |
download | chromium_src-4421b8c0cdcda67bfbdca6b75d44aef5e204e860.zip chromium_src-4421b8c0cdcda67bfbdca6b75d44aef5e204e860.tar.gz chromium_src-4421b8c0cdcda67bfbdca6b75d44aef5e204e860.tar.bz2 |
Merge 139167 - Add NOTIFICATION_TAB_CONTENTS_DESTROYED when a TabContentsWrapper is about to be torn down. Code that wants to access TabContentsWrappers (and their members) safely should listen to this rather than NOTIFICATION_WEB_CONTENTS_DESTROYED.
This fixes a crash in GoogleURLTracker that tried to access the already-NULLed infobar_tab_helper() on the TCW. The other points changed in this CL probably work fine today, but using this notification is more future-proof if we muck with destruction order (and sometimes slightly simpler to boot).
This also eliminates one use of NOTIFICATION_WEB_CONTENTS_DESTROYED entirely; there was some hacky code in task_manager_resource_providers.cc that tried to use it to backstop listening for another notification. Because the notification order is different with the new notification this wouldn't work; it also seems totally bogus anyway, so I just ripped it out.
Finally, this adds a public getter for whether a TabContentsWrapper is being destroyed, and switches most places that were checking for the similar WebContents::IsBeingDestroyed() flag to use this instead. This is usually more correct (since a number of places would check for WebContents destruction but if not found start accessing pieces of the TabContentsWrapper).
BUG=128512
TEST=none
Review URL: https://chromiumcodereview.appspot.com/10445028
TBR=pkasting@chromium.org
Review URL: https://chromiumcodereview.appspot.com/10454102
git-svn-id: svn://svn.chromium.org/chrome/branches/1132/src@139928 0039d316-1c4b-4281-b951-d872f2087c98
16 files changed, 83 insertions, 91 deletions
diff --git a/chrome/browser/sync/glue/session_change_processor.cc b/chrome/browser/sync/glue/session_change_processor.cc index cf146c8..79d5eb5 100644 --- a/chrome/browser/sync/glue/session_change_processor.cc +++ b/chrome/browser/sync/glue/session_change_processor.cc @@ -139,19 +139,15 @@ void SessionChangeProcessor::Observe( break; } - case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: { + case chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED: { TabContentsWrapper* tab_contents_wrapper = - TabContentsWrapper::GetCurrentWrapperForContents( - content::Source<WebContents>(source).ptr()); - if (!tab_contents_wrapper) { - return; - } + content::Source<TabContentsWrapper>(source).ptr(); SyncedTabDelegate* tab = tab_contents_wrapper->synced_tab_delegate(); if (!tab || tab->profile() != profile_) { return; } modified_tabs.push_back(tab); - DVLOG(1) << "Received NOTIFICATION_WEB_CONTENTS_DESTROYED for profile " + DVLOG(1) << "Received NOTIFICATION_TAB_CONTENTS_DESTROYED for profile " << profile_; break; } @@ -354,8 +350,7 @@ void SessionChangeProcessor::StartObserving() { return; notification_registrar_.Add(this, chrome::NOTIFICATION_TAB_PARENTED, content::NotificationService::AllSources()); - notification_registrar_.Add(this, - content::NOTIFICATION_WEB_CONTENTS_DESTROYED, + notification_registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED, content::NotificationService::AllSources()); notification_registrar_.Add(this, content::NOTIFICATION_NAV_LIST_PRUNED, content::NotificationService::AllSources()); diff --git a/chrome/browser/tabs/tab_strip_model.cc b/chrome/browser/tabs/tab_strip_model.cc index ad67ca9..bf92305 100644 --- a/chrome/browser/tabs/tab_strip_model.cc +++ b/chrome/browser/tabs/tab_strip_model.cc @@ -73,7 +73,7 @@ TabStripModel::TabStripModel(TabStripModelDelegate* delegate, Profile* profile) order_controller_(NULL) { DCHECK(delegate_); registrar_.Add(this, - content::NOTIFICATION_WEB_CONTENTS_DESTROYED, + chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED, content::NotificationService::AllBrowserContextsAndSources()); registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, @@ -1006,11 +1006,12 @@ void TabStripModel::Observe(int type, const content::NotificationSource& source, const content::NotificationDetails& details) { switch (type) { - case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: { + case chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED: { // Sometimes, on qemu, it seems like a WebContents object can be destroyed // while we still have a reference to it. We need to break this reference // here so we don't crash later. - int index = GetWrapperIndex(content::Source<WebContents>(source).ptr()); + int index = GetIndexOfTabContents( + content::Source<TabContentsWrapper>(source).ptr()); if (index != TabStripModel::kNoTab) { // Note that we only detach the contents here, not close it - it's // already been closed. We just want to undo our bookkeeping. diff --git a/chrome/browser/tabs/tab_strip_model_unittest.cc b/chrome/browser/tabs/tab_strip_model_unittest.cc index 178fe53..c9dae4d 100644 --- a/chrome/browser/tabs/tab_strip_model_unittest.cc +++ b/chrome/browser/tabs/tab_strip_model_unittest.cc @@ -26,6 +26,7 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "chrome/browser/ui/webui/ntp/new_tab_ui.h" +#include "chrome/common/chrome_notification_types.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/url_constants.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" @@ -59,9 +60,8 @@ class DeleteTabContentsOnDestroyedObserver TabContentsWrapper* tab_to_delete) : source_(source), tab_to_delete_(tab_to_delete) { - registrar_.Add(this, - content::NOTIFICATION_WEB_CONTENTS_DESTROYED, - content::Source<WebContents>(source->web_contents())); + registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED, + content::Source<TabContentsWrapper>(source)); } virtual void Observe(int type, diff --git a/chrome/browser/task_manager/task_manager_resource_providers.cc b/chrome/browser/task_manager/task_manager_resource_providers.cc index 327ea9a..a910100 100644 --- a/chrome/browser/task_manager/task_manager_resource_providers.cc +++ b/chrome/browser/task_manager/task_manager_resource_providers.cc @@ -397,12 +397,6 @@ void TaskManagerTabContentsResourceProvider::StartUpdating() { content::NotificationService::AllBrowserContextsAndSources()); registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, content::NotificationService::AllBrowserContextsAndSources()); - // TAB_CONTENTS_DISCONNECTED should be enough to know when to remove a - // resource. This is an attempt at mitigating a crasher that seem to - // indicate a resource is still referencing a deleted WebContents - // (http://crbug.com/7321). - registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, - content::NotificationService::AllBrowserContextsAndSources()); registrar_.Add(this, chrome::NOTIFICATION_INSTANT_COMMITTED, content::NotificationService::AllBrowserContextsAndSources()); } @@ -422,9 +416,6 @@ void TaskManagerTabContentsResourceProvider::StopUpdating() { this, content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, content::NotificationService::AllBrowserContextsAndSources()); registrar_.Remove( - this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, - content::NotificationService::AllBrowserContextsAndSources()); - registrar_.Remove( this, chrome::NOTIFICATION_INSTANT_COMMITTED, content::NotificationService::AllBrowserContextsAndSources()); @@ -520,12 +511,6 @@ void TaskManagerTabContentsResourceProvider::Observe(int type, Remove(tab_contents); Add(tab_contents); break; - case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: - // If this DCHECK is triggered, it could explain http://crbug.com/7321 . - DCHECK(resources_.find(tab_contents) == - resources_.end()) << "TAB_CONTENTS_DESTROYED with no associated " - "TAB_CONTENTS_DISCONNECTED"; - // Fall through. case content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED: Remove(tab_contents); break; diff --git a/chrome/browser/ui/blocked_content/blocked_content_tab_helper.cc b/chrome/browser/ui/blocked_content/blocked_content_tab_helper.cc index 2d09a71..38f29c5 100644 --- a/chrome/browser/ui/blocked_content/blocked_content_tab_helper.cc +++ b/chrome/browser/ui/blocked_content/blocked_content_tab_helper.cc @@ -50,9 +50,8 @@ void BlockedContentTabHelper::DidNavigateMainFrame( void BlockedContentTabHelper::PopupNotificationVisibilityChanged( bool visible) { - if (web_contents()->IsBeingDestroyed()) - return; - tab_contents_wrapper_->content_settings()->SetPopupsBlocked(visible); + if (!tab_contents_wrapper_->in_destructor()) + tab_contents_wrapper_->content_settings()->SetPopupsBlocked(visible); } void BlockedContentTabHelper::SendNotification(TabContentsWrapper* contents, diff --git a/chrome/browser/ui/cocoa/applescript/window_applescript.mm b/chrome/browser/ui/cocoa/applescript/window_applescript.mm index 5a5f095..c46b357 100644 --- a/chrome/browser/ui/cocoa/applescript/window_applescript.mm +++ b/chrome/browser/ui/cocoa/applescript/window_applescript.mm @@ -151,13 +151,13 @@ for (int i = 0; i < browser_->tab_count(); ++i) { // Check to see if tab is closing. - if (browser_->GetWebContentsAt(i)->IsBeingDestroyed()) { + TabContentsWrapper* tab_contents = browser_->GetTabContentsWrapperAt(i); + if (tab_contents->in_destructor()) { continue; } scoped_nsobject<TabAppleScript> tab( - [[TabAppleScript alloc] - initWithTabContent:(browser_->GetTabContentsWrapperAt(i))]); + [[TabAppleScript alloc] initWithTabContent:tab_contents]); [tab setContainer:self property:AppleScript::kTabsProperty]; [tabs addObject:tab]; diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc index 4978542..6cf65de 100644 --- a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc +++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc @@ -542,8 +542,8 @@ ContentSettingBubbleModel::ContentSettingBubbleModel( : tab_contents_(tab_contents), profile_(profile), content_type_(content_type) { - registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, - content::Source<WebContents>(tab_contents->web_contents())); + registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED, + content::Source<TabContentsWrapper>(tab_contents)); registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, content::Source<Profile>(profile_)); } @@ -576,17 +576,12 @@ void ContentSettingBubbleModel::Observe( int type, const content::NotificationSource& source, const content::NotificationDetails& details) { - switch (type) { - case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: - DCHECK(source == - content::Source<WebContents>(tab_contents_->web_contents())); - tab_contents_ = NULL; - break; - case chrome::NOTIFICATION_PROFILE_DESTROYED: - DCHECK(source == content::Source<Profile>(profile_)); - profile_ = NULL; - break; - default: - NOTREACHED(); + if (type == chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED) { + DCHECK_EQ(tab_contents_, content::Source<TabContentsWrapper>(source).ptr()); + tab_contents_ = NULL; + } else { + DCHECK_EQ(chrome::NOTIFICATION_PROFILE_DESTROYED, type); + DCHECK_EQ(profile_, content::Source<Profile>(source).ptr()); + profile_ = NULL; } } diff --git a/chrome/browser/ui/gtk/browser_window_gtk.cc b/chrome/browser/ui/gtk/browser_window_gtk.cc index 394dbce..cb9543c 100644 --- a/chrome/browser/ui/gtk/browser_window_gtk.cc +++ b/chrome/browser/ui/gtk/browser_window_gtk.cc @@ -1328,7 +1328,7 @@ void BrowserWindowGtk::ActiveTabChanged(TabContentsWrapper* old_contents, int index, bool user_gesture) { TRACE_EVENT0("ui::gtk", "BrowserWindowGtk::ActiveTabChanged"); - if (old_contents && !old_contents->web_contents()->IsBeingDestroyed()) + if (old_contents && !old_contents->in_destructor()) old_contents->web_contents()->GetView()->StoreFocus(); // Update various elements that are interested in knowing the current diff --git a/chrome/browser/ui/gtk/tab_contents_container_gtk.cc b/chrome/browser/ui/gtk/tab_contents_container_gtk.cc index 7a543b2..5055fbe 100644 --- a/chrome/browser/ui/gtk/tab_contents_container_gtk.cc +++ b/chrome/browser/ui/gtk/tab_contents_container_gtk.cc @@ -9,8 +9,8 @@ #include "base/i18n/rtl.h" #include "chrome/browser/ui/gtk/status_bubble_gtk.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" +#include "chrome/common/chrome_notification_types.h" #include "content/public/browser/notification_source.h" -#include "content/public/browser/notification_types.h" #include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/web_contents.h" #include "ui/base/gtk/gtk_expanded_container.h" @@ -67,8 +67,8 @@ void TabContentsContainerGtk::Init() { void TabContentsContainerGtk::SetTab(TabContentsWrapper* tab) { HideTab(tab_); if (tab_) { - registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, - content::Source<WebContents>(tab_->web_contents())); + registrar_.Remove(this, chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED, + content::Source<TabContentsWrapper>(tab_)); } tab_ = tab; @@ -80,8 +80,8 @@ void TabContentsContainerGtk::SetTab(TabContentsWrapper* tab) { } else if (tab_) { // Otherwise we actually have to add it to the widget hierarchy. PackTab(tab); - registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, - content::Source<WebContents>(tab_->web_contents())); + registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED, + content::Source<TabContentsWrapper>(tab_)); } } @@ -98,8 +98,8 @@ void TabContentsContainerGtk::SetPreview(TabContentsWrapper* preview) { preview_ = preview; PackTab(preview); - registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, - content::Source<WebContents>(preview_->web_contents())); + registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED, + content::Source<TabContentsWrapper>(preview_)); } void TabContentsContainerGtk::RemovePreview() { @@ -112,8 +112,8 @@ void TabContentsContainerGtk::RemovePreview() { if (preview_widget) gtk_container_remove(GTK_CONTAINER(expanded_), preview_widget); - registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, - content::Source<WebContents>(preview_->web_contents())); + registrar_.Remove(this, chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED, + content::Source<TabContentsWrapper>(preview_)); preview_ = NULL; } @@ -178,9 +178,9 @@ void TabContentsContainerGtk::Observe( int type, const content::NotificationSource& source, const content::NotificationDetails& details) { - DCHECK(type == content::NOTIFICATION_WEB_CONTENTS_DESTROYED); - - WebContentsDestroyed(content::Source<WebContents>(source).ptr()); + DCHECK_EQ(chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED, type); + WebContentsDestroyed( + content::Source<TabContentsWrapper>(source)->web_contents()); } void TabContentsContainerGtk::WebContentsDestroyed(WebContents* contents) { diff --git a/chrome/browser/ui/gtk/tabs/dragged_tab_controller_gtk.cc b/chrome/browser/ui/gtk/tabs/dragged_tab_controller_gtk.cc index b003ca4..c73f322 100644 --- a/chrome/browser/ui/gtk/tabs/dragged_tab_controller_gtk.cc +++ b/chrome/browser/ui/gtk/tabs/dragged_tab_controller_gtk.cc @@ -18,8 +18,8 @@ #include "chrome/browser/ui/gtk/tabs/dragged_view_gtk.h" #include "chrome/browser/ui/gtk/tabs/tab_strip_gtk.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" +#include "chrome/common/chrome_notification_types.h" #include "content/public/browser/notification_source.h" -#include "content/public/browser/notification_types.h" #include "content/public/browser/web_contents.h" #include "ui/base/gtk/gtk_screen_util.h" #include "ui/gfx/screen.h" @@ -163,10 +163,8 @@ DraggedTabData DraggedTabControllerGtk::InitDraggedTabData(TabGtk* tab) { DraggedTabData dragged_tab_data(tab, contents, original_delegate, source_model_index, pinned, mini); - registrar_.Add( - this, - content::NOTIFICATION_WEB_CONTENTS_DESTROYED, - content::Source<WebContents>(dragged_tab_data.contents_->web_contents())); + registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED, + content::Source<TabContentsWrapper>(dragged_tab_data.contents_)); return dragged_tab_data; } @@ -227,13 +225,15 @@ void DraggedTabControllerGtk::Observe( int type, const content::NotificationSource& source, const content::NotificationDetails& details) { - DCHECK(type == content::NOTIFICATION_WEB_CONTENTS_DESTROYED); - WebContents* destroyed_contents = content::Source<WebContents>(source).ptr(); + DCHECK_EQ(chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED, type); + TabContentsWrapper* destroyed_tab_contents = + content::Source<TabContentsWrapper>(source).ptr(); + WebContents* destroyed_web_contents = destroyed_tab_contents->web_contents(); for (size_t i = 0; i < drag_data_->size(); ++i) { - if (drag_data_->get(i)->contents_->web_contents() == destroyed_contents) { + if (drag_data_->get(i)->contents_ == destroyed_tab_contents) { // One of the tabs we're dragging has been destroyed. Cancel the drag. - if (destroyed_contents->GetDelegate() == this) - destroyed_contents->SetDelegate(NULL); + if (destroyed_web_contents->GetDelegate() == this) + destroyed_web_contents->SetDelegate(NULL); drag_data_->get(i)->contents_ = NULL; drag_data_->get(i)->original_delegate_ = NULL; EndDragImpl(TAB_DESTROYED); @@ -845,10 +845,8 @@ void DraggedTabControllerGtk::CleanUpDraggedTabs() { if (attached_tabstrip_ != source_tabstrip_) { for (size_t i = 0; i < drag_data_->size(); ++i) { if (drag_data_->get(i)->contents_) { - registrar_.Remove( - this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, - content::Source<WebContents>( - drag_data_->get(i)->contents_->web_contents())); + registrar_.Remove(this, chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED, + content::Source<TabContentsWrapper>(drag_data_->get(i)->contents_)); } source_tabstrip_->DestroyDraggedTab(drag_data_->get(i)->tab_); drag_data_->get(i)->tab_ = NULL; diff --git a/chrome/browser/ui/sync/tab_contents_wrapper_synced_tab_delegate.cc b/chrome/browser/ui/sync/tab_contents_wrapper_synced_tab_delegate.cc index cc7c126..c5eb182 100644 --- a/chrome/browser/ui/sync/tab_contents_wrapper_synced_tab_delegate.cc +++ b/chrome/browser/ui/sync/tab_contents_wrapper_synced_tab_delegate.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -29,7 +29,7 @@ SessionID::id_type TabContentsWrapperSyncedTabDelegate::GetSessionId() const { } bool TabContentsWrapperSyncedTabDelegate::IsBeingDestroyed() const { - return tab_contents_wrapper_->web_contents()->IsBeingDestroyed(); + return tab_contents_wrapper_->in_destructor(); } Profile* TabContentsWrapperSyncedTabDelegate::profile() const { diff --git a/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc b/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc index 5e457ea..824eb17 100644 --- a/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc +++ b/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc @@ -45,7 +45,9 @@ #include "chrome/browser/ui/sync/one_click_signin_helper.h" #include "chrome/browser/ui/sync/tab_contents_wrapper_synced_tab_delegate.h" #include "chrome/browser/ui/tab_contents/core_tab_helper.h" +#include "chrome/common/chrome_notification_types.h" #include "chrome/common/chrome_switches.h" +#include "content/public/browser/notification_service.h" #include "content/public/browser/web_contents.h" using content::WebContents; @@ -157,6 +159,11 @@ TabContentsWrapper::TabContentsWrapper(WebContents* contents) TabContentsWrapper::~TabContentsWrapper() { in_destructor_ = true; + content::NotificationService::current()->Notify( + chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED, + content::Source<TabContentsWrapper>(this), + content::NotificationService::NoDetails()); + // Need to tear down infobars before the WebContents goes away. // TODO(avi): Can we get this handled by the tab helper itself? infobar_tab_helper_.reset(); diff --git a/chrome/browser/ui/tab_contents/tab_contents_wrapper.h b/chrome/browser/ui/tab_contents/tab_contents_wrapper.h index 3fc5e14..83a5d3f 100644 --- a/chrome/browser/ui/tab_contents/tab_contents_wrapper.h +++ b/chrome/browser/ui/tab_contents/tab_contents_wrapper.h @@ -105,6 +105,9 @@ class TabContentsWrapper : public content::WebContentsObserver { // Returns the Profile that is associated with this TabContentsWrapper. Profile* profile() const; + // True if this TabContentsWrapper is being torn down. + bool in_destructor() const { return in_destructor_; } + // Tab Helpers --------------------------------------------------------------- AutocompleteHistoryManager* autocomplete_history_manager() { diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index e2ab96b..aa702e1 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc @@ -1361,7 +1361,7 @@ void BrowserView::TabDeactivated(TabContentsWrapper* contents) { // We do not store the focus when closing the tab to work-around bug 4633. // Some reports seem to show that the focus manager and/or focused view can // be garbage at that point, it is not clear why. - if (!contents->web_contents()->IsBeingDestroyed()) + if (!contents->in_destructor()) contents->web_contents()->GetView()->StoreFocus(); } diff --git a/chrome/browser/ui/views/tabs/default_tab_drag_controller.cc b/chrome/browser/ui/views/tabs/default_tab_drag_controller.cc index 523e5e4..f87aa3e 100644 --- a/chrome/browser/ui/views/tabs/default_tab_drag_controller.cc +++ b/chrome/browser/ui/views/tabs/default_tab_drag_controller.cc @@ -393,10 +393,8 @@ void DefaultTabDragController::InitTabDragData(BaseTab* tab, drag_data->contents = GetModel(source_tabstrip_)->GetTabContentsAt( drag_data->source_model_index); drag_data->pinned = source_tabstrip_->IsTabPinned(tab); - registrar_.Add( - this, - content::NOTIFICATION_WEB_CONTENTS_DESTROYED, - content::Source<WebContents>(drag_data->contents->web_contents())); + registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED, + content::Source<TabContentsWrapper>(drag_data->contents)); // We need to be the delegate so we receive messages about stuff, otherwise // our dragged WebContents may be replaced and subsequently @@ -514,13 +512,15 @@ void DefaultTabDragController::Observe( int type, const content::NotificationSource& source, const content::NotificationDetails& details) { - DCHECK_EQ(type, content::NOTIFICATION_WEB_CONTENTS_DESTROYED); - WebContents* destroyed_contents = content::Source<WebContents>(source).ptr(); + DCHECK_EQ(chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED, type); + TabContentsWrapper* destroyed_tab_contents = + content::Source<TabContentsWrapper>(source).ptr(); + WebContents* destroyed_web_contents = destroyed_tab_contents->web_contents(); for (size_t i = 0; i < drag_data_.size(); ++i) { - if (drag_data_[i].contents->web_contents() == destroyed_contents) { + if (drag_data_[i].contents == destroyed_tab_contents) { // One of the tabs we're dragging has been destroyed. Cancel the drag. - if (destroyed_contents->GetDelegate() == this) - destroyed_contents->SetDelegate(NULL); + if (destroyed_web_contents->GetDelegate() == this) + destroyed_web_contents->SetDelegate(NULL); drag_data_[i].contents = NULL; drag_data_[i].original_delegate = NULL; EndDragImpl(TAB_DESTROYED); diff --git a/chrome/common/chrome_notification_types.h b/chrome/common/chrome_notification_types.h index 3734b2c..5e42fda 100644 --- a/chrome/common/chrome_notification_types.h +++ b/chrome/common/chrome_notification_types.h @@ -159,10 +159,19 @@ enum NotificationType { // Source<NavigationController> with a pointer to the controller for the // closed tab. No details are expected. // - // See also content::NOTIFICATION_WEB_CONTENTS_DESTROYED, which is sent when - // the WebContents containing the NavigationController is destroyed. + // See also NOTIFICATION_TAB_CONTENTS_DESTROYED, which is sent when the + // TabContentsWrapper is destroyed, and + // content::NOTIFICATION_WEB_CONTENTS_DESTROYED, which is sent when the + // WebContents containing the NavigationController is destroyed. NOTIFICATION_TAB_CLOSING, + // Sent when a TabContentsWrapper is being destroyed. At this point it's safe + // to call TabContentsWrapper member functions, which is not true of the + // similar content::NOTIFICATION_WEB_CONTENTS_DESTROYED that fires later + // during teardown. The source is a Source<TabContentsWrapper>. There are no + // details. + NOTIFICATION_TAB_CONTENTS_DESTROYED, + // Stuff inside the tabs --------------------------------------------------- // Sent when the bookmark bubble hides. The source is the profile, the |