Commit db752d0b authored by arthursonzogni's avatar arthursonzogni Committed by Commit Bot

bfcache: Disable for WebBluetooth.

A page using the WebBluetooth API shouldn't be frozen and shouldn't enter the
BackForwardCache.

When navigating away from a page:
 1) The Bluetooth connection should be released.
 2) The tab indicator should be removed.

This won't happen if the RenderFrameHost is kept in the back-forward
cache.

Some background on why we sometimes need to disable bfcache:
https://docs.google.com/document/d/1NjZeusdS1kyEkZyfLggndU1A6qVt0Y1sa-LRUxnMoK8

Bug: 1001087
Change-Id: I27cb850ed6e94de440486b33111332811942c930
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1837936
Commit-Queue: Arthur Sonzogni <arthursonzogni@chromium.org>
Reviewed-by: default avatarReilly Grant <reillyg@chromium.org>
Reviewed-by: default avatarAlexander Timin <altimin@chromium.org>
Reviewed-by: default avatarAlex Moshchuk <alexmos@chromium.org>
Cr-Commit-Position: refs/heads/master@{#705031}
parent 127bb6a8
...@@ -2,30 +2,28 @@ ...@@ -2,30 +2,28 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "base/command_line.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/test/scoped_feature_list.h" #include "base/test/scoped_feature_list.h"
#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/in_process_browser_test.h"
#include "components/network_session_configurator/common/network_switches.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/content_features.h" #include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/back_forward_cache_util.h"
#include "content/public/test/browser_test_utils.h" #include "content/public/test/browser_test_utils.h"
#include "content/public/test/test_utils.h" #include "content/public/test/test_utils.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
#include "device/bluetooth/test/mock_bluetooth_adapter.h"
#include "net/dns/mock_host_resolver.h" #include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/embedded_test_server.h"
class ChromeBackForwardCacheBrowserTest : public InProcessBrowserTest { class ChromeBackForwardCacheBrowserTest : public InProcessBrowserTest {
public: public:
ChromeBackForwardCacheBrowserTest() { ChromeBackForwardCacheBrowserTest() = default;
scoped_feature_list_.InitAndEnableFeatureWithParameters( ~ChromeBackForwardCacheBrowserTest() override = default;
features::kBackForwardCache,
{
// Set a very long TTL before expiration (longer than the test
// timeout) so tests that are expecting deletion don't pass when
// they shouldn't.
{"TimeToLiveInBackForwardCacheInSeconds", "3600"},
});
}
~ChromeBackForwardCacheBrowserTest() override {}
void SetUpOnMainThread() override { void SetUpOnMainThread() override {
host_resolver()->AddRule("*", "127.0.0.1"); host_resolver()->AddRule("*", "127.0.0.1");
...@@ -45,6 +43,26 @@ class ChromeBackForwardCacheBrowserTest : public InProcessBrowserTest { ...@@ -45,6 +43,26 @@ class ChromeBackForwardCacheBrowserTest : public InProcessBrowserTest {
} }
protected: protected:
void SetUpCommandLine(base::CommandLine* command_line) override {
// For using an HTTPS server.
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kIgnoreCertificateErrors);
// For using WebBluetooth.
command_line->AppendSwitch(
switches::kEnableExperimentalWebPlatformFeatures);
scoped_feature_list_.InitAndEnableFeatureWithParameters(
features::kBackForwardCache,
{
// Set a very long TTL before expiration (longer than the test
// timeout) so tests that are expecting deletion don't pass when
// they shouldn't.
{"TimeToLiveInBackForwardCacheInSeconds", "3600"},
});
InProcessBrowserTest::SetUpCommandLine(command_line);
}
content::WebContents* web_contents() const { content::WebContents* web_contents() const {
return browser()->tab_strip_model()->GetActiveWebContents(); return browser()->tab_strip_model()->GetActiveWebContents();
} }
...@@ -144,3 +162,40 @@ IN_PROC_BROWSER_TEST_F(ChromeBackForwardCacheBrowserTest, BasicIframe) { ...@@ -144,3 +162,40 @@ IN_PROC_BROWSER_TEST_F(ChromeBackForwardCacheBrowserTest, BasicIframe) {
EXPECT_EQ("rfh_a", content::EvalJs(rfh_a, "token")); EXPECT_EQ("rfh_a", content::EvalJs(rfh_a, "token"));
EXPECT_EQ("rfh_b", content::EvalJs(rfh_b, "token")); EXPECT_EQ("rfh_b", content::EvalJs(rfh_b, "token"));
} }
IN_PROC_BROWSER_TEST_F(ChromeBackForwardCacheBrowserTest, WebBluetooth) {
// Fake the BluetoothAdapter to say it's present.
scoped_refptr<device::MockBluetoothAdapter> adapter =
new testing::NiceMock<device::MockBluetoothAdapter>;
device::BluetoothAdapterFactory::SetAdapterForTesting(adapter);
// WebBluetooth requires HTTPS.
net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
https_server.AddDefaultHandlers(GetChromeTestDataDir());
https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_OK);
ASSERT_TRUE(https_server.Start());
GURL url(https_server.GetURL("a.com", "/back_forward_cache/no-favicon.html"));
EXPECT_TRUE(content::NavigateToURL(web_contents(), url));
content::BackForwardCacheDisabledTester tester;
EXPECT_EQ("device not found", content::EvalJs(current_frame_host(), R"(
new Promise(resolve => {
navigator.bluetooth.requestDevice({
filters: [
{ services: [0x1802, 0x1803] },
]
})
.then(() => resolve("device found"))
.catch(() => resolve("device not found"))
});
)"));
EXPECT_TRUE(tester.IsDisabledForFrameWithReason(
current_frame_host()->GetProcess()->GetID(),
current_frame_host()->GetRoutingID(), "WebBluetooth"));
ASSERT_TRUE(embedded_test_server()->Start());
content::RenderFrameDeletedObserver delete_observer(current_frame_host());
EXPECT_TRUE(content::NavigateToURL(web_contents(), GetURL("b.com")));
delete_observer.WaitUntilDeleted();
}
...@@ -6272,6 +6272,7 @@ void RenderFrameHostImpl::AXContentTreeDataToAXTreeData(ui::AXTreeData* dst) { ...@@ -6272,6 +6272,7 @@ void RenderFrameHostImpl::AXContentTreeDataToAXTreeData(ui::AXTreeData* dst) {
void RenderFrameHostImpl::CreateWebBluetoothService( void RenderFrameHostImpl::CreateWebBluetoothService(
mojo::PendingReceiver<blink::mojom::WebBluetoothService> receiver) { mojo::PendingReceiver<blink::mojom::WebBluetoothService> receiver) {
BackForwardCache::DisableForRenderFrameHost(this, "WebBluetooth");
// RFHI owns |web_bluetooth_services_| and |web_bluetooth_service| owns the // RFHI owns |web_bluetooth_services_| and |web_bluetooth_service| owns the
// |receiver_| which may run the error handler. |receiver_| can't run the // |receiver_| which may run the error handler. |receiver_| can't run the
// error handler after it's destroyed so it can't run after the RFHI is // error handler after it's destroyed so it can't run after the RFHI is
......
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