summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcreis <creis@chromium.org>2015-05-27 09:13:17 -0700
committerCommit bot <commit-bot@chromium.org>2015-05-27 16:13:54 +0000
commit89a0f782193755ad7a0b93c58dbcc1b96528405f (patch)
tree427065bf2bf7eabae88fc659cdf6ae3255138666
parent0a5834c562d3455f3e70c50506453d19170e0b51 (diff)
downloadchromium_src-89a0f782193755ad7a0b93c58dbcc1b96528405f.zip
chromium_src-89a0f782193755ad7a0b93c58dbcc1b96528405f.tar.gz
chromium_src-89a0f782193755ad7a0b93c58dbcc1b96528405f.tar.bz2
Dismiss browser plugin modal dialogs when the embedder needs to.
Test from wjmaclean@. PDF simply shows an alert dialog using script. BUG=482380 TEST=See bug for repro steps. Review URL: https://codereview.chromium.org/1150843002 Cr-Commit-Position: refs/heads/master@{#331584}
-rw-r--r--chrome/browser/ui/browser_browsertest.cc26
-rw-r--r--chrome/test/data/alert_dialog.pdfbin0 -> 1083 bytes
-rw-r--r--content/browser/browser_plugin/browser_plugin_embedder.cc14
-rw-r--r--content/browser/browser_plugin/browser_plugin_embedder.h6
-rw-r--r--content/browser/web_contents/web_contents_impl.cc21
-rw-r--r--content/browser/web_contents/web_contents_impl.h4
6 files changed, 65 insertions, 6 deletions
diff --git a/chrome/browser/ui/browser_browsertest.cc b/chrome/browser/ui/browser_browsertest.cc
index 68eb19f..99cdde0 100644
--- a/chrome/browser/ui/browser_browsertest.cc
+++ b/chrome/browser/ui/browser_browsertest.cc
@@ -586,6 +586,32 @@ IN_PROC_BROWSER_TEST_F(BrowserTest, SadTabCancelsSubframeDialogs) {
ui_test_utils::NavigateToURL(browser(), url2);
}
+// Make sure modal dialogs within a guestview are closed when an interstitial
+// page is showing. See crbug.com/482380.
+IN_PROC_BROWSER_TEST_F(BrowserTest, InterstitialCancelsGuestViewDialogs) {
+ // Navigate to a PDF, which is loaded within a guestview.
+ ASSERT_TRUE(test_server()->Start());
+ GURL pdf_with_dialog(test_server()->GetURL("files/alert_dialog.pdf"));
+ ui_test_utils::NavigateToURL(browser(), pdf_with_dialog);
+
+ AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog();
+ EXPECT_TRUE(alert->IsValid());
+ AppModalDialogQueue* dialog_queue = AppModalDialogQueue::GetInstance();
+ EXPECT_TRUE(dialog_queue->HasActiveDialog());
+
+ WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents();
+
+ TestInterstitialPage* interstitial =
+ new TestInterstitialPage(contents, false, GURL());
+ content::WaitForInterstitialAttach(contents);
+
+ // The interstitial should have closed the dialog.
+ EXPECT_TRUE(contents->ShowingInterstitialPage());
+ EXPECT_FALSE(dialog_queue->HasActiveDialog());
+
+ interstitial->DontProceed();
+}
+
// Test for crbug.com/22004. Reloading a page with a before unload handler and
// then canceling the dialog should not leave the throbber spinning.
IN_PROC_BROWSER_TEST_F(BrowserTest, ReloadThenCancelBeforeUnload) {
diff --git a/chrome/test/data/alert_dialog.pdf b/chrome/test/data/alert_dialog.pdf
new file mode 100644
index 0000000..5c20ec5
--- /dev/null
+++ b/chrome/test/data/alert_dialog.pdf
Binary files differ
diff --git a/content/browser/browser_plugin/browser_plugin_embedder.cc b/content/browser/browser_plugin/browser_plugin_embedder.cc
index cee9b43..e563df0 100644
--- a/content/browser/browser_plugin/browser_plugin_embedder.cc
+++ b/content/browser/browser_plugin/browser_plugin_embedder.cc
@@ -64,6 +64,20 @@ void BrowserPluginEmbedder::ScreenInfoChanged() {
&BrowserPluginEmbedder::NotifyScreenInfoChanged));
}
+// static
+bool BrowserPluginEmbedder::CancelDialogs(WebContents* guest_web_contents) {
+ static_cast<WebContentsImpl*>(guest_web_contents)
+ ->CancelActiveAndPendingDialogs();
+
+ // Returns false to iterate over all guests.
+ return false;
+}
+
+void BrowserPluginEmbedder::CancelGuestDialogs() {
+ GetBrowserPluginGuestManager()->ForEachGuest(
+ web_contents(), base::Bind(&BrowserPluginEmbedder::CancelDialogs));
+}
+
void BrowserPluginEmbedder::StartDrag(BrowserPluginGuest* guest) {
guest_started_drag_ = guest->AsWeakPtr();
guest_drag_ending_ = false;
diff --git a/content/browser/browser_plugin/browser_plugin_embedder.h b/content/browser/browser_plugin/browser_plugin_embedder.h
index 721814f..842d3ee 100644
--- a/content/browser/browser_plugin/browser_plugin_embedder.h
+++ b/content/browser/browser_plugin/browser_plugin_embedder.h
@@ -56,6 +56,9 @@ class CONTENT_EXPORT BrowserPluginEmbedder : public WebContentsObserver {
// Called when the screen info has changed.
void ScreenInfoChanged();
+ // Closes modal dialogs in all of the guests.
+ void CancelGuestDialogs();
+
// Called by WebContentsViewGuest when a drag operation is started within
// |guest|. This |guest| will be signaled at the end of the drag operation.
void StartDrag(BrowserPluginGuest* guest);
@@ -84,6 +87,9 @@ class CONTENT_EXPORT BrowserPluginEmbedder : public WebContentsObserver {
// Notifies a guest that the embedder's screen info has changed.
static bool NotifyScreenInfoChanged(WebContents* guest_web_contents);
+ // Closes modal dialogs in |guest_web_contents|.
+ static bool CancelDialogs(WebContents* guest_web_contents);
+
static bool UnlockMouseIfNecessaryCallback(bool* mouse_unlocked,
WebContents* guest);
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index e5c61bb..407c25e 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -678,6 +678,13 @@ int WebContentsImpl::GetRoutingID() const {
return GetRenderViewHost()->GetRoutingID();
}
+void WebContentsImpl::CancelActiveAndPendingDialogs() {
+ if (dialog_manager_)
+ dialog_manager_->CancelActiveAndPendingDialogs(this);
+ if (browser_plugin_embedder_)
+ browser_plugin_embedder_->CancelGuestDialogs();
+}
+
int WebContentsImpl::GetFullscreenWidgetRoutingID() const {
return fullscreen_widget_routing_id_;
}
@@ -1995,8 +2002,7 @@ void WebContentsImpl::AttachInterstitialPage(
// Cancel any visible dialogs so that they don't interfere with the
// interstitial.
- if (dialog_manager_)
- dialog_manager_->CancelActiveAndPendingDialogs(this);
+ CancelActiveAndPendingDialogs();
FOR_EACH_OBSERVER(WebContentsObserver, observers_,
DidAttachInterstitialPage());
@@ -2752,8 +2758,8 @@ void WebContentsImpl::DidNavigateAnyFramePostCommit(
has_accessed_initial_document_ = false;
// If we navigate off the page, close all JavaScript dialogs.
- if (dialog_manager_ && !details.is_in_page)
- dialog_manager_->CancelActiveAndPendingDialogs(this);
+ if (!details.is_in_page)
+ CancelActiveAndPendingDialogs();
// Notify observers about navigation.
FOR_EACH_OBSERVER(WebContentsObserver, observers_,
@@ -3604,8 +3610,7 @@ void WebContentsImpl::RenderViewTerminated(RenderViewHost* rvh,
ExitFullscreenMode();
// Cancel any visible dialogs so they are not left dangling over the sad tab.
- if (dialog_manager_)
- dialog_manager_->CancelActiveAndPendingDialogs(this);
+ CancelActiveAndPendingDialogs();
if (delegate_)
delegate_->HideValidationMessage(this);
@@ -4054,6 +4059,10 @@ void WebContentsImpl::CancelModalDialogsForRenderManager() {
// deferrer would prevent us from swapping out. We also clear the state
// because this is a cross-process navigation, which means that it's a new
// site that should not have to pay for the sins of its predecessor.
+ //
+ // Note that we don't bother telling browser_plugin_embedder_ because the
+ // cross-process navigation will either destroy the browser plugins or not
+ // require their dialogs to close.
if (dialog_manager_)
dialog_manager_->ResetDialogState(this);
}
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index 91a395f..709071f 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -158,6 +158,10 @@ class CONTENT_EXPORT WebContentsImpl
// already exist.
void CreateBrowserPluginEmbedderIfNecessary();
+ // Cancels modal dialogs in this WebContents, as well as in any browser
+ // plugins it is hosting.
+ void CancelActiveAndPendingDialogs();
+
// Gets the current fullscreen render widget's routing ID. Returns
// MSG_ROUTING_NONE when there is no fullscreen render widget.
int GetFullscreenWidgetRoutingID() const;