summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorshess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-31 22:44:09 +0000
committershess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-31 22:44:09 +0000
commit4e8c4f9f882e8ccd85a8c629cbb58d8819773db1 (patch)
tree4ad1238a7f4e0d780c079788c36dfd91097114df
parent8267dfd1852d76a08e0b5e64710914a6b7367055 (diff)
downloadchromium_src-4e8c4f9f882e8ccd85a8c629cbb58d8819773db1.zip
chromium_src-4e8c4f9f882e8ccd85a8c629cbb58d8819773db1.tar.gz
chromium_src-4e8c4f9f882e8ccd85a8c629cbb58d8819773db1.tar.bz2
[Mac] Hung-renderer dialogs observes the initiating tab in case it goes away.
The user can close the tab out from under the dialog, at which point killing from the dialog will cause a crash. BUG=89909 TEST=See bug, monitor crash server. Review URL: http://codereview.chromium.org/7810011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@99064 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/ui/cocoa/hung_renderer_controller.h9
-rw-r--r--chrome/browser/ui/cocoa/hung_renderer_controller.mm34
2 files changed, 43 insertions, 0 deletions
diff --git a/chrome/browser/ui/cocoa/hung_renderer_controller.h b/chrome/browser/ui/cocoa/hung_renderer_controller.h
index 957e5fb..7d4fd1c 100644
--- a/chrome/browser/ui/cocoa/hung_renderer_controller.h
+++ b/chrome/browser/ui/cocoa/hung_renderer_controller.h
@@ -22,9 +22,11 @@
#import "base/mac/cocoa_protocols.h"
#import "base/memory/scoped_nsobject.h"
+#import "base/memory/scoped_ptr.h"
@class MultiKeyEquivalentButton;
class TabContents;
+class TabContentsObserverBridge;
@interface HungRendererController : NSWindowController<NSTableViewDataSource> {
@private
@@ -38,6 +40,9 @@ class TabContents;
// NULL while this dialog is open.
TabContents* hungContents_;
+ // Observes |hungContents_| in case it closes while the panel is up.
+ scoped_ptr<TabContentsObserverBridge> hungContentsObserver_;
+
// Backing data for |tableView_|. Titles of each TabContents that
// shares a renderer process with |hungContents_|.
scoped_nsobject<NSArray> hungTitles_;
@@ -65,6 +70,10 @@ class TabContents;
// If |contents| has a different process, this function does nothing.
- (void)endForTabContents:(TabContents*)contents;
+// Called by |hungContentsObserver_| to indicate that |hungContents_|
+// has gone away.
+- (void)renderViewGone;
+
@end // HungRendererController
diff --git a/chrome/browser/ui/cocoa/hung_renderer_controller.mm b/chrome/browser/ui/cocoa/hung_renderer_controller.mm
index f8dc950..bab2472 100644
--- a/chrome/browser/ui/cocoa/hung_renderer_controller.mm
+++ b/chrome/browser/ui/cocoa/hung_renderer_controller.mm
@@ -36,6 +36,29 @@ namespace {
HungRendererController* g_instance = NULL;
} // namespace
+class TabContentsObserverBridge : public TabContentsObserver {
+ public:
+ TabContentsObserverBridge(TabContents* tab_contents,
+ HungRendererController* controller)
+ : TabContentsObserver(tab_contents),
+ controller_(controller) {
+ }
+
+ protected:
+ // TabContentsObserver overrides:
+ virtual void RenderViewGone() OVERRIDE {
+ [controller_ renderViewGone];
+ }
+ virtual void TabContentsDestroyed(TabContents* tab) OVERRIDE {
+ [controller_ renderViewGone];
+ }
+
+ private:
+ HungRendererController* controller_; // weak
+
+ DISALLOW_COPY_AND_ASSIGN(TabContentsObserverBridge);
+};
+
@implementation HungRendererController
- (id)initWithWindowNibName:(NSString*)nibName {
@@ -134,9 +157,15 @@ HungRendererController* g_instance = NULL;
[self autorelease];
}
+// TODO(shess): This could observe all of the tabs referenced in the
+// loop, updating the dialog and keeping it up so long as any remain.
+// Tabs closed by their renderer will close the dialog (that's
+// activity!), so it would not add much value. Also, the views
+// implementation only monitors the initiating tab.
- (void)showForTabContents:(TabContents*)contents {
DCHECK(contents);
hungContents_ = contents;
+ hungContentsObserver_.reset(new TabContentsObserverBridge(contents, self));
scoped_nsobject<NSMutableArray> titles([[NSMutableArray alloc] init]);
scoped_nsobject<NSMutableArray> favicons([[NSMutableArray alloc] init]);
for (TabContentsIterator it; !it.done(); ++it) {
@@ -167,6 +196,11 @@ HungRendererController* g_instance = NULL;
}
}
+- (void)renderViewGone {
+ // Cannot call performClose:, because the close button is disabled.
+ [self close];
+}
+
@end
@implementation HungRendererController (JustForTesting)