Commit c2ace594 authored by horo's avatar horo Committed by Commit bot

Don't speculatively start ServiceWorker if it doesn't have FetchEvent handler

ServiceWorkers without FetchEvent handlers should not be started up on navigation, see https://crbug.com/616502#c38

BUG=616502,640132

Review-Url: https://codereview.chromium.org/2393503002
Cr-Commit-Position: refs/heads/master@{#422796}
parent 66c9f33d
...@@ -523,6 +523,8 @@ IN_PROC_BROWSER_TEST_F(ChromeServiceWorkerFetchPPAPIPrivateTest, ...@@ -523,6 +523,8 @@ IN_PROC_BROWSER_TEST_F(ChromeServiceWorkerFetchPPAPIPrivateTest,
class ServiceWorkerSpeculativeLaunchTest : public ChromeServiceWorkerTest { class ServiceWorkerSpeculativeLaunchTest : public ChromeServiceWorkerTest {
protected: protected:
static const std::string kNavigationHintLinkMouseDownMetricName;
ServiceWorkerSpeculativeLaunchTest() {} ServiceWorkerSpeculativeLaunchTest() {}
~ServiceWorkerSpeculativeLaunchTest() override {} ~ServiceWorkerSpeculativeLaunchTest() override {}
...@@ -532,12 +534,74 @@ class ServiceWorkerSpeculativeLaunchTest : public ChromeServiceWorkerTest { ...@@ -532,12 +534,74 @@ class ServiceWorkerSpeculativeLaunchTest : public ChromeServiceWorkerTest {
features::kSpeculativeLaunchServiceWorker.name); features::kSpeculativeLaunchServiceWorker.name);
} }
void WriteTestHtmlFile() {
WriteFile(
FILE_PATH_LITERAL("test.html"),
"<script>"
"navigator.serviceWorker.register('./sw.js', {scope: './scope.html'})"
" .then(function(reg) {"
" reg.addEventListener('updatefound', function() {"
" var worker = reg.installing;"
" worker.addEventListener('statechange', function() {"
" if (worker.state == 'activated')"
" document.title = 'READY';"
" });"
" });"
" });"
"</script>"
"<body style='margin:0; padding:0;'>"
"<a href='./scope.html' "
"style='position:fixed; width:1px; height:1px;'></a>"
"</body>");
}
void RunNavigationHintTest() {
embedded_test_server()->ServeFilesFromDirectory(
service_worker_dir_.GetPath());
ASSERT_TRUE(embedded_test_server()->Start());
content::ServiceWorkerContext* sw_context =
content::BrowserContext::GetDefaultStoragePartition(
browser()->profile())
->GetServiceWorkerContext();
const base::string16 expected_title1 = base::ASCIIToUTF16("READY");
content::TitleWatcher title_watcher1(
browser()->tab_strip_model()->GetActiveWebContents(), expected_title1);
ui_test_utils::NavigateToURL(browser(),
embedded_test_server()->GetURL("/test.html"));
EXPECT_EQ(expected_title1, title_watcher1.WaitAndGetTitle());
histogram_tester_.ExpectBucketCount("ServiceWorker.StartNewWorker.Status",
0 /* SERVICE_WORKER_OK */, 1);
sw_context->StopAllServiceWorkersForOrigin(
embedded_test_server()->base_url());
const base::string16 expected_title2 = base::ASCIIToUTF16("Done");
content::TitleWatcher title_watcher2(
browser()->tab_strip_model()->GetActiveWebContents(), expected_title2);
histogram_tester_.ExpectTotalCount(kNavigationHintLinkMouseDownMetricName,
0);
content::SimulateMouseClickAt(
browser()->tab_strip_model()->GetActiveWebContents(), 0,
blink::WebMouseEvent::Button::Left, gfx::Point(0, 0));
EXPECT_EQ(expected_title2, title_watcher2.WaitAndGetTitle());
}
base::HistogramTester histogram_tester_; base::HistogramTester histogram_tester_;
private: private:
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerSpeculativeLaunchTest); DISALLOW_COPY_AND_ASSIGN(ServiceWorkerSpeculativeLaunchTest);
}; };
// static
const std::string
ServiceWorkerSpeculativeLaunchTest::kNavigationHintLinkMouseDownMetricName =
"ServiceWorker.StartWorker.StatusByPurpose_"
"NAVIGATION_HINT_LINK_MOUSE_DOWN";
IN_PROC_BROWSER_TEST_F(ServiceWorkerSpeculativeLaunchTest, MouseDown) { IN_PROC_BROWSER_TEST_F(ServiceWorkerSpeculativeLaunchTest, MouseDown) {
WriteFile( WriteFile(
FILE_PATH_LITERAL("sw.js"), FILE_PATH_LITERAL("sw.js"),
...@@ -545,63 +609,21 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerSpeculativeLaunchTest, MouseDown) { ...@@ -545,63 +609,21 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerSpeculativeLaunchTest, MouseDown) {
" e.respondWith(new Response('<title>Done</title>'," " e.respondWith(new Response('<title>Done</title>',"
" {headers: {'Content-Type': 'text/html'}}));" " {headers: {'Content-Type': 'text/html'}}));"
"};"); "};");
WriteFile( WriteTestHtmlFile();
FILE_PATH_LITERAL("test.html"), RunNavigationHintTest();
"<script>" // The service worker must be started by a navigation hint.
"navigator.serviceWorker.register('./sw.js', {scope: './scope/'})" histogram_tester_.ExpectBucketCount(kNavigationHintLinkMouseDownMetricName,
" .then(function(reg) {"
" reg.addEventListener('updatefound', function() {"
" var worker = reg.installing;"
" worker.addEventListener('statechange', function() {"
" if (worker.state == 'activated')"
" document.title = 'READY';"
" });"
" });"
" });"
"</script>"
"<body style='margin:0; padding:0;'>"
"<a href='./scope/' style='position:fixed; width:1px; height:1px;'></a>"
"</body>");
embedded_test_server()->ServeFilesFromDirectory(
service_worker_dir_.GetPath());
ASSERT_TRUE(embedded_test_server()->Start());
content::ServiceWorkerContext* sw_context =
content::BrowserContext::GetDefaultStoragePartition(browser()->profile())
->GetServiceWorkerContext();
const base::string16 expected_title1 = base::ASCIIToUTF16("READY");
content::TitleWatcher title_watcher1(
browser()->tab_strip_model()->GetActiveWebContents(), expected_title1);
ui_test_utils::NavigateToURL(browser(),
embedded_test_server()->GetURL("/test.html"));
EXPECT_EQ(expected_title1, title_watcher1.WaitAndGetTitle());
histogram_tester_.ExpectBucketCount("ServiceWorker.StartNewWorker.Status",
0 /* SERVICE_WORKER_OK */, 1); 0 /* SERVICE_WORKER_OK */, 1);
}
sw_context->StopAllServiceWorkersForOrigin( IN_PROC_BROWSER_TEST_F(ServiceWorkerSpeculativeLaunchTest,
embedded_test_server()->base_url()); NoFetchEventHandler) {
WriteFile(FILE_PATH_LITERAL("sw.js"), "// no fetch event handler.");
const base::string16 expected_title2 = base::ASCIIToUTF16("Done"); WriteFile(FILE_PATH_LITERAL("scope.html"), "<title>Done</title>");
content::TitleWatcher title_watcher2( WriteTestHtmlFile();
browser()->tab_strip_model()->GetActiveWebContents(), expected_title2); RunNavigationHintTest();
// The service worker must NOT be started by a navigation hint.
histogram_tester_.ExpectTotalCount( histogram_tester_.ExpectTotalCount(kNavigationHintLinkMouseDownMetricName, 0);
"ServiceWorker.StartWorker.StatusByPurpose_NAVIGATION_HINT_LINK_MOUSE_"
"DOWN",
0);
content::SimulateMouseClickAt(
browser()->tab_strip_model()->GetActiveWebContents(), 0,
blink::WebMouseEvent::Button::Left, gfx::Point(0, 0));
EXPECT_EQ(expected_title2, title_watcher2.WaitAndGetTitle());
// The service worker must be started by a navigation hint.
histogram_tester_.ExpectBucketCount(
"ServiceWorker.StartWorker.StatusByPurpose_NAVIGATION_HINT_LINK_MOUSE_"
"DOWN",
0 /* SERVICE_WORKER_OK */, 1);
} }
} // namespace } // namespace
...@@ -341,6 +341,13 @@ void ServiceWorkerContextWrapper::DidFindRegistrationForNavigationHint( ...@@ -341,6 +341,13 @@ void ServiceWorkerContextWrapper::DidFindRegistrationForNavigationHint(
return; return;
} }
if (registration->active_version()->fetch_handler_existence() ==
ServiceWorkerVersion::FetchHandlerExistence::DOES_NOT_EXIST) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::Bind(callback, false));
return;
}
// Add the process reference of |render_process_id| not to launch a new // Add the process reference of |render_process_id| not to launch a new
// renderer process for the service worker. // renderer process for the service worker.
context_core_->process_manager()->AddProcessReferenceToPattern( context_core_->process_manager()->AddProcessReferenceToPattern(
......
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