Commit 1a2efd08 authored by Timothy Loh's avatar Timothy Loh Committed by Commit Bot

Fix clearing of hidden permission prompts in background tabs

This patch fixes a bug where permission prompts that were hidden due to
tab switching wouldn't be cleared upon navigation/destruction, leading
to in some cases a DCHECK being hit or prompts persisting across navs.

Bug: 757394
Change-Id: Iae960fb241ed635bd4eea93cd21cc50657aa4a9e
Reviewed-on: https://chromium-review.googlesource.com/627349Reviewed-by: default avatarBen Wells <benwells@chromium.org>
Commit-Queue: Timothy Loh <timloh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#496617}
parent 096b36b4
...@@ -443,7 +443,7 @@ void PermissionRequestManager::CleanUpRequests() { ...@@ -443,7 +443,7 @@ void PermissionRequestManager::CleanUpRequests() {
} }
queued_requests_.clear(); queued_requests_.clear();
if (view_) if (!requests_.empty())
FinalizeBubble(PermissionAction::IGNORED); FinalizeBubble(PermissionAction::IGNORED);
} }
......
...@@ -29,7 +29,9 @@ ...@@ -29,7 +29,9 @@
#include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h" #include "content/public/browser/render_process_host.h"
#include "content/public/test/browser_test_utils.h" #include "content/public/test/browser_test_utils.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_utils.h" #include "content/public/test/test_utils.h"
#include "media/base/media_switches.h"
#include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/embedded_test_server.h"
namespace test { namespace test {
...@@ -89,6 +91,12 @@ class PermissionRequestManagerBrowserTest : public InProcessBrowserTest { ...@@ -89,6 +91,12 @@ class PermissionRequestManagerBrowserTest : public InProcessBrowserTest {
mock_permission_prompt_factory_.reset(); mock_permission_prompt_factory_.reset();
} }
void SetUpCommandLine(base::CommandLine* command_line) override {
// Enable fake devices so we can test getUserMedia() on devices without
// physical media devices.
command_line->AppendSwitch(switches::kUseFakeDeviceForMediaStream);
}
PermissionRequestManager* GetPermissionRequestManager() { PermissionRequestManager* GetPermissionRequestManager() {
return PermissionRequestManager::FromWebContents( return PermissionRequestManager::FromWebContents(
browser()->tab_strip_model()->GetActiveWebContents()); browser()->tab_strip_model()->GetActiveWebContents());
...@@ -390,6 +398,95 @@ IN_PROC_BROWSER_TEST_F(PermissionRequestManagerBrowserTest, InPageNavigation) { ...@@ -390,6 +398,95 @@ IN_PROC_BROWSER_TEST_F(PermissionRequestManagerBrowserTest, InPageNavigation) {
EXPECT_EQ(1, bubble_factory()->TotalRequestCount()); EXPECT_EQ(1, bubble_factory()->TotalRequestCount());
} }
// Prompts are only shown for active tabs and (on Desktop) hidden on tab
// switching
IN_PROC_BROWSER_TEST_F(PermissionRequestManagerBrowserTest, MultipleTabs) {
ASSERT_TRUE(embedded_test_server()->Start());
ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
browser(), embedded_test_server()->GetURL("/empty.html"), 1);
ui_test_utils::NavigateToURLWithDisposition(
browser(), embedded_test_server()->GetURL("/empty.html"),
WindowOpenDisposition::NEW_FOREGROUND_TAB,
ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
// SetUp() only creates a mock prompt factory for the first tab.
MockPermissionPromptFactory* bubble_factory_0 = bubble_factory();
std::unique_ptr<MockPermissionPromptFactory> bubble_factory_1(
base::MakeUnique<MockPermissionPromptFactory>(
GetPermissionRequestManager()));
TabStripModel* tab_strip_model = browser()->tab_strip_model();
ASSERT_EQ(2, tab_strip_model->count());
ASSERT_EQ(1, tab_strip_model->active_index());
// Request geolocation in foreground tab, prompt should be shown.
ExecuteScriptAndGetValue(
tab_strip_model->GetWebContentsAt(1)->GetMainFrame(),
"navigator.geolocation.getCurrentPosition(function(){});");
EXPECT_EQ(1, bubble_factory_1->show_count());
EXPECT_FALSE(bubble_factory_0->is_visible());
EXPECT_TRUE(bubble_factory_1->is_visible());
tab_strip_model->ActivateTabAt(0, false);
EXPECT_FALSE(bubble_factory_0->is_visible());
EXPECT_FALSE(bubble_factory_1->is_visible());
tab_strip_model->ActivateTabAt(1, false);
EXPECT_EQ(2, bubble_factory_1->show_count());
EXPECT_FALSE(bubble_factory_0->is_visible());
EXPECT_TRUE(bubble_factory_1->is_visible());
// Request notification in background tab. No prompt is shown until the tab
// itself is activated.
ExecuteScriptAndGetValue(tab_strip_model->GetWebContentsAt(0)->GetMainFrame(),
"Notification.requestPermission()");
EXPECT_FALSE(bubble_factory_0->is_visible());
EXPECT_EQ(2, bubble_factory_1->show_count());
tab_strip_model->ActivateTabAt(0, false);
EXPECT_TRUE(bubble_factory_0->is_visible());
EXPECT_EQ(1, bubble_factory()->show_count());
EXPECT_EQ(2, bubble_factory_1->show_count());
}
IN_PROC_BROWSER_TEST_F(PermissionRequestManagerBrowserTest,
BackgroundTabNavigation) {
ASSERT_TRUE(embedded_test_server()->Start());
ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
browser(), embedded_test_server()->GetURL("/empty.html"), 1);
// Request camera, prompt should be shown.
ExecuteScriptAndGetValue(
browser()->tab_strip_model()->GetWebContentsAt(0)->GetMainFrame(),
"navigator.getUserMedia({video: true}, ()=>{}, ()=>{})");
bubble_factory()->WaitForPermissionBubble();
EXPECT_TRUE(bubble_factory()->is_visible());
EXPECT_EQ(1, bubble_factory()->show_count());
// SetUp() only creates a mock prompt factory for the first tab but this test
// doesn't request any permissions in the second tab so it doesn't need one.
ui_test_utils::NavigateToURLWithDisposition(
browser(), embedded_test_server()->GetURL("/empty.html"),
WindowOpenDisposition::NEW_FOREGROUND_TAB,
ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
// Navigate background tab, prompt should be removed.
ExecuteScriptAndGetValue(
browser()->tab_strip_model()->GetWebContentsAt(0)->GetMainFrame(),
"window.location = 'simple.html'");
content::TestNavigationObserver observer(
browser()->tab_strip_model()->GetWebContentsAt(0));
observer.Wait();
EXPECT_FALSE(bubble_factory()->is_visible());
browser()->tab_strip_model()->ActivateTabAt(0, false);
EXPECT_FALSE(bubble_factory()->is_visible());
EXPECT_EQ(1, bubble_factory()->show_count());
}
// Bubble requests should not be shown when the killswitch is on. // Bubble requests should not be shown when the killswitch is on.
IN_PROC_BROWSER_TEST_F(PermissionRequestManagerBrowserTest, IN_PROC_BROWSER_TEST_F(PermissionRequestManagerBrowserTest,
KillSwitchGeolocation) { KillSwitchGeolocation) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment