summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorflackr@chromium.org <flackr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-19 16:10:51 +0000
committerflackr@chromium.org <flackr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-19 16:10:51 +0000
commitc5e22aee57bd524acf0fb620192a05cdcfc4c1ab (patch)
tree860c7d622ab4ca210a17539235863112feea5adf /chrome
parent1da813714de79af80d4790b7797ea6788822c9be (diff)
downloadchromium_src-c5e22aee57bd524acf0fb620192a05cdcfc4c1ab.zip
chromium_src-c5e22aee57bd524acf0fb620192a05cdcfc4c1ab.tar.gz
chromium_src-c5e22aee57bd524acf0fb620192a05cdcfc4c1ab.tar.bz2
Close created HtmlDialogs on closing of the browser that opened them.
BUG=103595 TEST=Open a dialog from a new browser (test incognito browser too), and close that browser. The dialog should close avoiding the use of the invalid profile. Review URL: http://codereview.chromium.org/9051004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@118301 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/chromeos/choose_mobile_network_dialog.cc5
-rw-r--r--chrome/browser/chromeos/login/login_html_dialog.cc2
-rw-r--r--chrome/browser/chromeos/sim_dialog_delegate.cc5
-rw-r--r--chrome/browser/printing/cloud_print/cloud_print_setup_flow.cc10
-rw-r--r--chrome/browser/printing/print_dialog_cloud.cc9
-rw-r--r--chrome/browser/ui/browser.cc6
-rw-r--r--chrome/browser/ui/browser_dialogs.h10
-rw-r--r--chrome/browser/ui/cocoa/html_dialog_window_controller.h14
-rw-r--r--chrome/browser/ui/cocoa/html_dialog_window_controller.mm38
-rw-r--r--chrome/browser/ui/cocoa/html_dialog_window_controller_unittest.mm3
-rw-r--r--chrome/browser/ui/gtk/html_dialog_gtk.cc16
-rw-r--r--chrome/browser/ui/gtk/html_dialog_gtk.h7
-rw-r--r--chrome/browser/ui/views/html_dialog_view.cc13
-rw-r--r--chrome/browser/ui/views/html_dialog_view.h9
-rw-r--r--chrome/browser/ui/views/html_dialog_view_browsertest.cc10
-rw-r--r--chrome/browser/ui/views/keyboard_overlay_dialog_view.cc4
-rw-r--r--chrome/browser/ui/webui/html_dialog_controller.cc40
-rw-r--r--chrome/browser/ui/webui/html_dialog_controller.h41
-rw-r--r--chrome/browser/ui/webui/html_dialog_controller_browsertest.cc64
-rw-r--r--chrome/browser/ui/webui/task_manager_dialog.cc8
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--chrome/chrome_tests.gypi1
22 files changed, 254 insertions, 63 deletions
diff --git a/chrome/browser/chromeos/choose_mobile_network_dialog.cc b/chrome/browser/chromeos/choose_mobile_network_dialog.cc
index e525f62..19cf4d4 100644
--- a/chrome/browser/chromeos/choose_mobile_network_dialog.cc
+++ b/chrome/browser/chromeos/choose_mobile_network_dialog.cc
@@ -30,15 +30,16 @@ namespace chromeos {
// static
void ChooseMobileNetworkDialog::ShowDialog(gfx::NativeWindow owning_window) {
Profile* profile;
+ Browser* browser = NULL;
if (UserManager::Get()->user_is_logged_in()) {
- Browser* browser = BrowserList::GetLastActive();
+ browser = BrowserList::GetLastActive();
DCHECK(browser);
profile = browser->profile();
} else {
profile = ProfileManager::GetDefaultProfile();
}
HtmlDialogView* html_view =
- new HtmlDialogView(profile, new ChooseMobileNetworkDialog);
+ new HtmlDialogView(profile, browser, new ChooseMobileNetworkDialog);
html_view->InitDialog();
browser::CreateViewsWindow(owning_window, html_view, STYLE_FLUSH);
html_view->GetWidget()->Show();
diff --git a/chrome/browser/chromeos/login/login_html_dialog.cc b/chrome/browser/chromeos/login/login_html_dialog.cc
index d751a5c..b4e64bc 100644
--- a/chrome/browser/chromeos/login/login_html_dialog.cc
+++ b/chrome/browser/chromeos/login/login_html_dialog.cc
@@ -59,7 +59,7 @@ LoginHtmlDialog::~LoginHtmlDialog() {
void LoginHtmlDialog::Show() {
HtmlDialogView* html_view =
- new HtmlDialogView(ProfileManager::GetDefaultProfile(), this);
+ new HtmlDialogView(ProfileManager::GetDefaultProfile(), NULL, this);
#if defined(USE_AURA)
// TODO(saintlou): Until the new Bubble have been landed.
views::Widget::CreateWindowWithParent(html_view, parent_window_);
diff --git a/chrome/browser/chromeos/sim_dialog_delegate.cc b/chrome/browser/chromeos/sim_dialog_delegate.cc
index 4d6335f..c592708 100644
--- a/chrome/browser/chromeos/sim_dialog_delegate.cc
+++ b/chrome/browser/chromeos/sim_dialog_delegate.cc
@@ -49,15 +49,16 @@ namespace chromeos {
void SimDialogDelegate::ShowDialog(gfx::NativeWindow owning_window,
SimDialogMode mode) {
Profile* profile;
+ Browser* browser = NULL;
if (UserManager::Get()->user_is_logged_in()) {
- Browser* browser = BrowserList::GetLastActive();
+ browser = BrowserList::GetLastActive();
DCHECK(browser);
profile = browser->profile();
} else {
profile = ProfileManager::GetDefaultProfile();
}
HtmlDialogView* html_view =
- new HtmlDialogView(profile, new SimDialogDelegate(mode));
+ new HtmlDialogView(profile, browser, new SimDialogDelegate(mode));
html_view->InitDialog();
browser::CreateViewsWindow(owning_window, html_view, STYLE_FLUSH);
html_view->GetWidget()->Show();
diff --git a/chrome/browser/printing/cloud_print/cloud_print_setup_flow.cc b/chrome/browser/printing/cloud_print/cloud_print_setup_flow.cc
index 0304866..6709e62 100644
--- a/chrome/browser/printing/cloud_print/cloud_print_setup_flow.cc
+++ b/chrome/browser/printing/cloud_print/cloud_print_setup_flow.cc
@@ -62,6 +62,7 @@ CloudPrintSetupFlow* CloudPrintSetupFlow::OpenDialog(
const base::WeakPtr<Delegate>& delegate,
gfx::NativeWindow parent_window) {
DCHECK(profile);
+ Browser* browser = BrowserList::GetLastActiveWithProfile(profile);
// Set the arguments for showing the gaia login page.
DictionaryValue args;
args.SetString("user", "");
@@ -83,12 +84,9 @@ CloudPrintSetupFlow* CloudPrintSetupFlow::OpenDialog(
// invoked in the context of a "token expired" notfication. If we don't have
// a brower, use the underlying dialog system to show the dialog without
// using a browser.
- if (!parent_window) {
- Browser* browser = BrowserList::GetLastActive();
- if (browser && browser->window())
- parent_window = browser->window()->GetNativeHandle();
- }
- browser::ShowHtmlDialog(parent_window, profile, flow, STYLE_GENERIC);
+ if (!parent_window && browser && browser->window())
+ parent_window = browser->window()->GetNativeHandle();
+ browser::ShowHtmlDialog(parent_window, profile, browser, flow, STYLE_GENERIC);
return flow;
}
diff --git a/chrome/browser/printing/print_dialog_cloud.cc b/chrome/browser/printing/print_dialog_cloud.cc
index ca5c0fd..579b73b 100644
--- a/chrome/browser/printing/print_dialog_cloud.cc
+++ b/chrome/browser/printing/print_dialog_cloud.cc
@@ -624,6 +624,7 @@ void CreateDialogImpl(const FilePath& path_to_file,
g_browser_process->profile_manager()->GetLoadedProfiles();
DCHECK_GT(loaded_profiles.size(), 0U);
profile = loaded_profiles[0];
+ browser = BrowserList::GetLastActiveWithProfile(profile);
}
DCHECK(profile);
PrefService* pref_service = profile->GetPrefs();
@@ -650,7 +651,7 @@ void CreateDialogImpl(const FilePath& path_to_file,
DCHECK(browser);
#if defined(USE_AURA)
HtmlDialogView* html_view =
- new HtmlDialogView(profile, dialog_delegate);
+ new HtmlDialogView(profile, browser, dialog_delegate);
views::Widget::CreateWindowWithParent(html_view,
browser->window()->GetNativeHandle());
html_view->InitDialog();
@@ -659,7 +660,11 @@ void CreateDialogImpl(const FilePath& path_to_file,
browser->BrowserShowHtmlDialog(dialog_delegate, NULL, STYLE_GENERIC);
#endif
} else {
- browser::ShowHtmlDialog(NULL, profile, dialog_delegate, STYLE_GENERIC);
+ browser::ShowHtmlDialog(NULL,
+ profile,
+ browser,
+ dialog_delegate,
+ STYLE_GENERIC);
}
}
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index ac18f52..3080871 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -1277,7 +1277,11 @@ gfx::NativeWindow Browser::BrowserShowHtmlDialog(
if (!parent_window)
parent_window = window_->GetNativeHandle();
- return browser::ShowHtmlDialog(parent_window, profile_, delegate, style);
+ return browser::ShowHtmlDialog(parent_window,
+ profile_,
+ this,
+ delegate,
+ style);
}
void Browser::BrowserRenderWidgetShowing() {
diff --git a/chrome/browser/ui/browser_dialogs.h b/chrome/browser/ui/browser_dialogs.h
index e395ad1..970f272 100644
--- a/chrome/browser/ui/browser_dialogs.h
+++ b/chrome/browser/ui/browser_dialogs.h
@@ -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.
@@ -36,12 +36,16 @@ void ShowAboutIPCDialog();
#endif // IPC_MESSAGE_LOG_ENABLED
// Creates and shows an HTML dialog with the given delegate and profile.
-// The window is automatically destroyed when it is closed.
+// The window is automatically destroyed when it is closed. |browser| can be
+// NULL if the profile used is not incognito, otherwise the window will be
+// closed if the browser is closed.
// Returns the created window.
//
// Make sure to use the returned window only when you know it is safe
// to do so, i.e. before OnDialogClosed() is called on the delegate.
-gfx::NativeWindow ShowHtmlDialog(gfx::NativeWindow parent, Profile* profile,
+gfx::NativeWindow ShowHtmlDialog(gfx::NativeWindow parent,
+ Profile* profile,
+ Browser* browser,
HtmlDialogUIDelegate* delegate,
DialogStyle style);
diff --git a/chrome/browser/ui/cocoa/html_dialog_window_controller.h b/chrome/browser/ui/cocoa/html_dialog_window_controller.h
index 2ba46a5..93d0d83 100644
--- a/chrome/browser/ui/cocoa/html_dialog_window_controller.h
+++ b/chrome/browser/ui/cocoa/html_dialog_window_controller.h
@@ -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.
@@ -13,6 +13,7 @@
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/ui/webui/html_dialog_ui.h"
+class Browser;
class HtmlDialogWindowDelegateBridge;
class Profile;
class TabContentsWrapper;
@@ -28,13 +29,15 @@ class TabContentsWrapper;
}
// Creates and shows an HtmlDialogWindowController with the given
-// delegate and profile. The window is automatically destroyed when
-// it is closed. Returns the created window.
+// delegate and profile whose lifetime is controlled by the given
+// browser. The window is automatically destroyed when it, or its
+// controlling browser is closed. Returns the created window.
//
// Make sure to use the returned window only when you know it is safe
// to do so, i.e. before OnDialogClosed() is called on the delegate.
+ (NSWindow*)showHtmlDialog:(HtmlDialogUIDelegate*)delegate
- profile:(Profile*)profile;
+ profile:(Profile*)profile
+ browser:(Browser*)browser;
@end
@@ -43,7 +46,8 @@ class TabContentsWrapper;
// This is the designated initializer. However, this is exposed only
// for testing; use showHtmlDialog instead.
- (id)initWithDelegate:(HtmlDialogUIDelegate*)delegate
- profile:(Profile*)profile;
+ profile:(Profile*)profile
+ browser:(Browser*)browser;
// Loads the HTML content from the delegate; this is not a lightweight
// process which is why it is not part of the constructor. Must be
diff --git a/chrome/browser/ui/cocoa/html_dialog_window_controller.mm b/chrome/browser/ui/cocoa/html_dialog_window_controller.mm
index a312567..f57af53 100644
--- a/chrome/browser/ui/cocoa/html_dialog_window_controller.mm
+++ b/chrome/browser/ui/cocoa/html_dialog_window_controller.mm
@@ -9,11 +9,13 @@
#include "base/property_bag.h"
#include "base/sys_string_conversions.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser.h"
#import "chrome/browser/ui/browser_dialogs.h"
#import "chrome/browser/ui/cocoa/browser_command_executor.h"
#import "chrome/browser/ui/cocoa/chrome_event_processing_window.h"
#include "chrome/browser/ui/dialog_style.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
+#include "chrome/browser/ui/webui/html_dialog_controller.h"
#include "chrome/browser/ui/webui/html_dialog_tab_contents_delegate.h"
#include "chrome/browser/ui/webui/html_dialog_ui.h"
#include "content/public/browser/native_web_keyboard_event.h"
@@ -33,6 +35,7 @@ public:
// All parameters must be non-NULL/non-nil.
HtmlDialogWindowDelegateBridge(HtmlDialogWindowController* controller,
Profile* profile,
+ Browser* browser,
HtmlDialogUIDelegate* delegate);
virtual ~HtmlDialogWindowDelegateBridge();
@@ -62,6 +65,7 @@ public:
private:
HtmlDialogWindowController* controller_; // weak
HtmlDialogUIDelegate* delegate_; // weak, owned by controller_
+ HtmlDialogController* dialog_controller_;
// Calls delegate_'s OnDialogClosed() exactly once, nulling it out
// afterwards so that no other HtmlDialogUIDelegate calls are sent
@@ -85,28 +89,25 @@ namespace browser {
gfx::NativeWindow ShowHtmlDialog(gfx::NativeWindow parent,
Profile* profile,
+ Browser* browser,
HtmlDialogUIDelegate* delegate,
DialogStyle style) {
- // It's not always safe to display an html dialog with an off the record
- // profile. If the last browser with that profile is closed it will go
- // away.
- // On most platforms we insist on the dialog being modal if we're off the
- // record to prevent that. That wont work on the Mac since we don't have
- // modal dialogs.
- // Fall back to the old (incorrect) behavior of grabbing the original
- // profile.
- // NOTE: Use the parent parameter once we implement modal dialogs.
return [HtmlDialogWindowController showHtmlDialog:delegate
- profile:profile->GetOriginalProfile()];
+ profile:profile
+ browser:browser];
}
} // namespace html_dialog_window_controller
HtmlDialogWindowDelegateBridge::HtmlDialogWindowDelegateBridge(
- HtmlDialogWindowController* controller, Profile* profile,
+ HtmlDialogWindowController* controller,
+ Profile* profile,
+ Browser* browser,
HtmlDialogUIDelegate* delegate)
: HtmlDialogTabContentsDelegate(profile),
- controller_(controller), delegate_(delegate) {
+ controller_(controller),
+ delegate_(delegate),
+ dialog_controller_(new HtmlDialogController(this, profile, browser)) {
DCHECK(controller_);
DCHECK(delegate_);
}
@@ -115,6 +116,7 @@ HtmlDialogWindowDelegateBridge::~HtmlDialogWindowDelegateBridge() {}
void HtmlDialogWindowDelegateBridge::WindowControllerClosed() {
Detach();
+ delete dialog_controller_;
controller_ = nil;
DelegateOnDialogClosed("");
}
@@ -250,17 +252,20 @@ void HtmlDialogWindowDelegateBridge::HandleKeyboardEvent(
// in once we implement modal dialogs.
+ (NSWindow*)showHtmlDialog:(HtmlDialogUIDelegate*)delegate
- profile:(Profile*)profile {
+ profile:(Profile*)profile
+ browser:(Browser*)browser {
HtmlDialogWindowController* htmlDialogWindowController =
[[HtmlDialogWindowController alloc] initWithDelegate:delegate
- profile:profile];
+ profile:profile
+ browser:browser];
[htmlDialogWindowController loadDialogContents];
[htmlDialogWindowController showWindow:nil];
return [htmlDialogWindowController window];
}
- (id)initWithDelegate:(HtmlDialogUIDelegate*)delegate
- profile:(Profile*)profile {
+ profile:(Profile*)profile
+ browser:(Browser*)browser {
DCHECK(delegate);
DCHECK(profile);
@@ -287,7 +292,8 @@ void HtmlDialogWindowDelegateBridge::HandleKeyboardEvent(
[window setTitle:base::SysUTF16ToNSString(delegate->GetDialogTitle())];
[window setMinSize:dialogRect.size];
[window center];
- delegate_.reset(new HtmlDialogWindowDelegateBridge(self, profile, delegate));
+ delegate_.reset(
+ new HtmlDialogWindowDelegateBridge(self, profile, browser, delegate));
return self;
}
diff --git a/chrome/browser/ui/cocoa/html_dialog_window_controller_unittest.mm b/chrome/browser/ui/cocoa/html_dialog_window_controller_unittest.mm
index e655e23..80f3cdc 100644
--- a/chrome/browser/ui/cocoa/html_dialog_window_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/html_dialog_window_controller_unittest.mm
@@ -90,7 +90,8 @@ TEST_F(HtmlDialogWindowControllerTest, showDialog) {
HtmlDialogWindowController* html_dialog_window_controller =
[[HtmlDialogWindowController alloc] initWithDelegate:&delegate_
- profile:profile()];
+ profile:profile()
+ browser:browser()];
[html_dialog_window_controller loadDialogContents];
[html_dialog_window_controller showWindow:nil];
diff --git a/chrome/browser/ui/gtk/html_dialog_gtk.cc b/chrome/browser/ui/gtk/html_dialog_gtk.cc
index 210e28c..12dfaa4 100644
--- a/chrome/browser/ui/gtk/html_dialog_gtk.cc
+++ b/chrome/browser/ui/gtk/html_dialog_gtk.cc
@@ -15,6 +15,7 @@
#include "chrome/browser/ui/gtk/gtk_util.h"
#include "chrome/browser/ui/gtk/tab_contents_container_gtk.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
+#include "chrome/browser/ui/webui/html_dialog_controller.h"
#include "chrome/browser/ui/webui/html_dialog_ui.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/native_web_keyboard_event.h"
@@ -24,19 +25,16 @@ using content::WebUIMessageHandler;
namespace browser {
-gfx::NativeWindow ShowHtmlDialog(gfx::NativeWindow parent, Profile* profile,
+gfx::NativeWindow ShowHtmlDialog(gfx::NativeWindow parent,
+ Profile* profile,
+ Browser* browser,
HtmlDialogUIDelegate* delegate,
DialogStyle style) {
- // It's not always safe to display an html dialog with an off the record
- // profile. If the last browser with that profile is closed it will go
- // away.
// Ignore style for now. The style parameter only used in the implementation
// in html_dialog_view.cc file.
// TODO (bshe): Add style parameter to HtmlDialogGtk.
- DCHECK(!profile->IsOffTheRecord() ||
- delegate->GetDialogModalType() != ui::MODAL_TYPE_NONE);
HtmlDialogGtk* html_dialog =
- new HtmlDialogGtk(profile, delegate, parent);
+ new HtmlDialogGtk(profile, browser, delegate, parent);
return html_dialog->InitDialog();
}
@@ -66,12 +64,14 @@ void SetDialogStyle() {
// HtmlDialogGtk, public:
HtmlDialogGtk::HtmlDialogGtk(Profile* profile,
+ Browser* browser,
HtmlDialogUIDelegate* delegate,
gfx::NativeWindow parent_window)
: HtmlDialogTabContentsDelegate(profile),
delegate_(delegate),
parent_window_(parent_window),
- dialog_(NULL) {
+ dialog_(NULL),
+ dialog_controller_(new HtmlDialogController(this, profile, browser)) {
}
HtmlDialogGtk::~HtmlDialogGtk() {
diff --git a/chrome/browser/ui/gtk/html_dialog_gtk.h b/chrome/browser/ui/gtk/html_dialog_gtk.h
index 2f3fe0d..52c06a7 100644
--- a/chrome/browser/ui/gtk/html_dialog_gtk.h
+++ b/chrome/browser/ui/gtk/html_dialog_gtk.h
@@ -19,6 +19,8 @@
typedef struct _GtkWidget GtkWidget;
+class Browser;
+class HtmlDialogController;
class Profile;
class TabContents;
class TabContentsContainerGtk;
@@ -27,7 +29,9 @@ class TabContentsWrapper;
class HtmlDialogGtk : public HtmlDialogTabContentsDelegate,
public HtmlDialogUIDelegate {
public:
- HtmlDialogGtk(Profile* profile, HtmlDialogUIDelegate* delegate,
+ HtmlDialogGtk(Profile* profile,
+ Browser* browser,
+ HtmlDialogUIDelegate* delegate,
gfx::NativeWindow parent_window);
virtual ~HtmlDialogGtk();
@@ -65,6 +69,7 @@ class HtmlDialogGtk : public HtmlDialogTabContentsDelegate,
GtkWidget* dialog_;
+ scoped_ptr<HtmlDialogController> dialog_controller_;
scoped_ptr<TabContentsWrapper> tab_;
scoped_ptr<TabContentsContainerGtk> tab_contents_container_;
diff --git a/chrome/browser/ui/views/html_dialog_view.cc b/chrome/browser/ui/views/html_dialog_view.cc
index d58608b..abe5c86 100644
--- a/chrome/browser/ui/views/html_dialog_view.cc
+++ b/chrome/browser/ui/views/html_dialog_view.cc
@@ -10,6 +10,7 @@
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "chrome/browser/ui/views/window.h"
+#include "chrome/browser/ui/webui/html_dialog_controller.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"
@@ -34,14 +35,10 @@ namespace browser {
// Declared in browser_dialogs.h so that others don't need to depend on our .h.
gfx::NativeWindow ShowHtmlDialog(gfx::NativeWindow parent,
Profile* profile,
+ Browser* browser,
HtmlDialogUIDelegate* delegate,
DialogStyle style) {
- // It's not always safe to display an html dialog with an off the record
- // profile. If the last browser with that profile is closed it will go
- // away.
- DCHECK(!profile->IsOffTheRecord() ||
- delegate->GetDialogModalType() != ui::MODAL_TYPE_NONE);
- HtmlDialogView* html_view = new HtmlDialogView(profile, delegate);
+ HtmlDialogView* html_view = new HtmlDialogView(profile, browser, delegate);
browser::CreateViewsWindow(parent, html_view, style);
html_view->InitDialog();
html_view->GetWidget()->Show();
@@ -54,11 +51,13 @@ gfx::NativeWindow ShowHtmlDialog(gfx::NativeWindow parent,
// HtmlDialogView, public:
HtmlDialogView::HtmlDialogView(Profile* profile,
+ Browser* browser,
HtmlDialogUIDelegate* delegate)
: DOMView(),
HtmlDialogTabContentsDelegate(profile),
initialized_(false),
- delegate_(delegate) {
+ delegate_(delegate),
+ dialog_controller_(new HtmlDialogController(this, profile, browser)) {
}
HtmlDialogView::~HtmlDialogView() {
diff --git a/chrome/browser/ui/views/html_dialog_view.h b/chrome/browser/ui/views/html_dialog_view.h
index fb439d0..fb5f3ce 100644
--- a/chrome/browser/ui/views/html_dialog_view.h
+++ b/chrome/browser/ui/views/html_dialog_view.h
@@ -19,6 +19,8 @@
#include "ui/views/widget/widget_delegate.h"
class Browser;
+class HtmlDialogController;
+class Profile;
////////////////////////////////////////////////////////////////////////////////
//
@@ -40,7 +42,9 @@ class HtmlDialogView
public views::WidgetDelegate,
public TabFirstRenderWatcher::Delegate {
public:
- HtmlDialogView(Profile* profile, HtmlDialogUIDelegate* delegate);
+ HtmlDialogView(Profile* profile,
+ Browser* browser,
+ HtmlDialogUIDelegate* delegate);
virtual ~HtmlDialogView();
// Initializes the contents of the dialog (the DOMView and the callbacks).
@@ -111,6 +115,9 @@ class HtmlDialogView
// using this variable.
HtmlDialogUIDelegate* delegate_;
+ // Controls lifetime of dialog.
+ scoped_ptr<HtmlDialogController> dialog_controller_;
+
DISALLOW_COPY_AND_ASSIGN(HtmlDialogView);
};
diff --git a/chrome/browser/ui/views/html_dialog_view_browsertest.cc b/chrome/browser/ui/views/html_dialog_view_browsertest.cc
index d1fb2b7..e98beb7 100644
--- a/chrome/browser/ui/views/html_dialog_view_browsertest.cc
+++ b/chrome/browser/ui/views/html_dialog_view_browsertest.cc
@@ -32,8 +32,10 @@ const int kInitialHeight = 40;
class TestHtmlDialogView: public HtmlDialogView {
public:
- TestHtmlDialogView(Profile* profile, HtmlDialogUIDelegate* delegate)
- : HtmlDialogView(profile, delegate),
+ TestHtmlDialogView(Profile* profile,
+ Browser* browser,
+ HtmlDialogUIDelegate* delegate)
+ : HtmlDialogView(profile, browser, delegate),
painted_(false),
should_quit_on_size_change_(false) {
delegate->GetDialogSize(&last_size_);
@@ -107,7 +109,7 @@ IN_PROC_BROWSER_TEST_F(HtmlDialogBrowserTest, MAYBE_SizeWindow) {
delegate->set_size(kInitialWidth, kInitialHeight);
TestHtmlDialogView* html_view =
- new TestHtmlDialogView(browser()->profile(), delegate);
+ new TestHtmlDialogView(browser()->profile(), browser(), delegate);
WebContents* web_contents = browser()->GetSelectedWebContents();
ASSERT_TRUE(web_contents != NULL);
views::Widget::CreateWindowWithParent(
@@ -188,7 +190,7 @@ IN_PROC_BROWSER_TEST_F(HtmlDialogBrowserTest, DISABLED_WebContentRendered) {
GURL(chrome::kChromeUIChromeURLsURL));
TestHtmlDialogView* html_view =
- new TestHtmlDialogView(browser()->profile(), delegate);
+ new TestHtmlDialogView(browser()->profile(), browser(), delegate);
WebContents* web_contents = browser()->GetSelectedWebContents();
ASSERT_TRUE(web_contents != NULL);
views::Widget::CreateWindowWithParent(
diff --git a/chrome/browser/ui/views/keyboard_overlay_dialog_view.cc b/chrome/browser/ui/views/keyboard_overlay_dialog_view.cc
index a1fcac6..366cf48 100644
--- a/chrome/browser/ui/views/keyboard_overlay_dialog_view.cc
+++ b/chrome/browser/ui/views/keyboard_overlay_dialog_view.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.
@@ -37,7 +37,7 @@ KeyboardOverlayDialogView::KeyboardOverlayDialogView(
Profile* profile,
HtmlDialogUIDelegate* delegate,
BrowserView* parent_view)
- : HtmlDialogView(profile, delegate),
+ : HtmlDialogView(profile, NULL, delegate),
parent_view_(parent_view) {
}
diff --git a/chrome/browser/ui/webui/html_dialog_controller.cc b/chrome/browser/ui/webui/html_dialog_controller.cc
new file mode 100644
index 0000000..a4642ce
--- /dev/null
+++ b/chrome/browser/ui/webui/html_dialog_controller.cc
@@ -0,0 +1,40 @@
+// 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.
+
+#include "chrome/browser/ui/webui/html_dialog_controller.h"
+
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/common/chrome_notification_types.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/browser/notification_source.h"
+
+HtmlDialogController::HtmlDialogController(HtmlDialogUIDelegate* delegate,
+ Profile* profile,
+ Browser* browser)
+ : dialog_delegate_(delegate) {
+ // It's only safe to show an off the record profile if we have a browser which
+ // has this profile to maintain its existence.
+ DCHECK(!profile->IsOffTheRecord() || (browser &&
+ browser->profile() == profile));
+ // If we're passed a browser it should own the profile we're using.
+ DCHECK(!browser || browser->profile() == profile);
+ if (browser) {
+ registrar_.Add(this,
+ chrome::NOTIFICATION_BROWSER_CLOSING,
+ content::Source<Browser>(browser));
+ }
+}
+
+// content::NotificationObserver implementation:
+void HtmlDialogController::Observe(
+ int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) {
+ DCHECK(type == chrome::NOTIFICATION_BROWSER_CLOSING);
+
+ // If the browser creating this dialog is closed, close the dialog to prevent
+ // using potentially destroyed profiles.
+ dialog_delegate_->OnDialogClosed(std::string());
+}
diff --git a/chrome/browser/ui/webui/html_dialog_controller.h b/chrome/browser/ui/webui/html_dialog_controller.h
new file mode 100644
index 0000000..6786475
--- /dev/null
+++ b/chrome/browser/ui/webui/html_dialog_controller.h
@@ -0,0 +1,41 @@
+// 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.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_HTML_DIALOG_CONTROLLER_H_
+#define CHROME_BROWSER_UI_WEBUI_HTML_DIALOG_CONTROLLER_H_
+#pragma once
+
+#include "chrome/browser/ui/webui/html_dialog_ui.h"
+#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_registrar.h"
+
+class Browser;
+class Profile;
+
+// This provides the common functionality for HtmlDialogs of notifying the
+// dialog that it should close when the browser that created it has closed to
+// avoid using an old Profile object.
+class HtmlDialogController : public content::NotificationObserver {
+ public:
+ HtmlDialogController(HtmlDialogUIDelegate* delegate,
+ Profile* profile,
+ Browser* browser);
+
+ // content::NotificationObserver implementation.
+ virtual void Observe(int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) OVERRIDE;
+
+ private:
+ // The delegate controlled by this instance. This class is owned by the
+ // delegate.
+ HtmlDialogUIDelegate* dialog_delegate_;
+
+ // Used for notification of parent browser closing.
+ content::NotificationRegistrar registrar_;
+
+ DISALLOW_COPY_AND_ASSIGN(HtmlDialogController);
+};
+
+#endif // CHROME_BROWSER_UI_WEBUI_HTML_DIALOG_CONTROLLER_H_
diff --git a/chrome/browser/ui/webui/html_dialog_controller_browsertest.cc b/chrome/browser/ui/webui/html_dialog_controller_browsertest.cc
new file mode 100644
index 0000000..1fadb62
--- /dev/null
+++ b/chrome/browser/ui/webui/html_dialog_controller_browsertest.cc
@@ -0,0 +1,64 @@
+// 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.
+
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/webui/test_html_dialog_ui_delegate.h"
+#include "chrome/common/url_constants.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+class TestDialogClosedDelegate : public test::TestHtmlDialogUIDelegate {
+ public:
+ TestDialogClosedDelegate()
+ : test::TestHtmlDialogUIDelegate(GURL(chrome::kChromeUIChromeURLsURL)),
+ dialog_closed_(false) {
+ }
+
+ // Overridden from HtmlDialogUIDelegate:
+ virtual ui::ModalType GetDialogModalType() const OVERRIDE {
+ return ui::MODAL_TYPE_NONE;
+ }
+
+ // Overridden from HtmlDialogUIDelegate:
+ virtual void OnDialogClosed(const std::string& json_retval) OVERRIDE {
+ dialog_closed_ = true;
+ }
+
+ bool dialog_closed() {
+ return dialog_closed_;
+ }
+
+ private:
+ bool dialog_closed_;
+};
+
+} // namespace
+
+class HtmlDialogControllerBrowserTest : public InProcessBrowserTest {
+ public:
+ HtmlDialogControllerBrowserTest() {}
+};
+
+// Tests that an HtmlDialog can be shown for an incognito browser and that when
+// that browser is closed the dialog created by that browser is closed.
+IN_PROC_BROWSER_TEST_F(HtmlDialogControllerBrowserTest, IncognitoBrowser) {
+ Browser* browser = CreateIncognitoBrowser();
+ scoped_ptr<TestDialogClosedDelegate> delegate(new TestDialogClosedDelegate());
+
+ // Create the dialog and make sure the initial "closed" state is what we
+ // expect.
+ browser->BrowserShowHtmlDialog(delegate.get(), NULL, STYLE_GENERIC);
+ ui_test_utils::RunAllPendingInMessageLoop();
+ ASSERT_FALSE(delegate->dialog_closed());
+
+ // Closing the browser should close the dialogs associated with that browser.
+ browser->CloseWindow();
+ ui_test_utils::RunAllPendingInMessageLoop();
+ ASSERT_TRUE(delegate->dialog_closed());
+}
diff --git a/chrome/browser/ui/webui/task_manager_dialog.cc b/chrome/browser/ui/webui/task_manager_dialog.cc
index 9bd6557..deca53f 100644
--- a/chrome/browser/ui/webui/task_manager_dialog.cc
+++ b/chrome/browser/ui/webui/task_manager_dialog.cc
@@ -11,6 +11,7 @@
#include "chrome/browser/platform_util.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/prefs/scoped_user_pref_update.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "chrome/browser/ui/browser_list.h"
@@ -168,7 +169,12 @@ void TaskManagerDialogImpl::OnCloseDialog() {
void TaskManagerDialogImpl::OpenHtmlDialog() {
Browser* browser = BrowserList::GetLastActive();
- window_ = browser->BrowserShowHtmlDialog(this, NULL, STYLE_GENERIC);
+ DCHECK(browser);
+ window_ = browser::ShowHtmlDialog(NULL,
+ browser->profile()->GetOriginalProfile(),
+ NULL,
+ this,
+ STYLE_GENERIC);
}
// ****************************************************
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index dbd5e99..2156f08 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -3830,6 +3830,8 @@
'browser/ui/webui/input_window_dialog_ui.h',
'browser/ui/webui/input_window_dialog_webui.cc',
'browser/ui/webui/input_window_dialog_webui.h',
+ 'browser/ui/webui/html_dialog_controller.cc',
+ 'browser/ui/webui/html_dialog_controller.h',
'browser/ui/webui/html_dialog_tab_contents_delegate.cc',
'browser/ui/webui/html_dialog_tab_contents_delegate.h',
'browser/ui/webui/html_dialog_ui.cc',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 8446758..2c36ff5 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -2734,6 +2734,7 @@
'browser/ui/webui/test_chrome_web_ui_factory_browsertest.cc',
'browser/ui/webui/bidi_checker_web_ui_test.cc',
'browser/ui/webui/bidi_checker_web_ui_test.h',
+ 'browser/ui/webui/html_dialog_controller_browsertest.cc',
'browser/ui/webui/net_internals/net_internals_ui_browsertest.cc',
'browser/ui/webui/net_internals/net_internals_ui_browsertest.h',
'browser/ui/webui/ntp/new_tab_ui_browsertest.cc',