1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/service_worker/service_worker_dispatcher_host.h"
7 #include "base/command_line.h"
8 #include "base/files/file_path.h"
9 #include "base/run_loop.h"
10 #include "content/browser/browser_thread_impl.h"
11 #include "content/browser/service_worker/embedded_worker_instance.h"
12 #include "content/browser/service_worker/embedded_worker_registry.h"
13 #include "content/browser/service_worker/embedded_worker_test_helper.h"
14 #include "content/browser/service_worker/service_worker_context_core.h"
15 #include "content/browser/service_worker/service_worker_context_wrapper.h"
16 #include "content/common/service_worker/embedded_worker_messages.h"
17 #include "content/common/service_worker/service_worker_messages.h"
18 #include "content/public/common/content_switches.h"
19 #include "content/public/test/mock_resource_context.h"
20 #include "content/public/test/test_browser_thread_bundle.h"
21 #include "content/test/test_content_browser_client.h"
22 #include "testing/gtest/include/gtest/gtest.h"
28 static void SaveStatusCallback(bool* called
,
29 ServiceWorkerStatusCode
* out
,
30 ServiceWorkerStatusCode status
) {
37 static const int kRenderProcessId
= 1;
38 static const int kRenderFrameId
= 1;
40 class TestingServiceWorkerDispatcherHost
: public ServiceWorkerDispatcherHost
{
42 TestingServiceWorkerDispatcherHost(
44 ServiceWorkerContextWrapper
* context_wrapper
,
45 ResourceContext
* resource_context
,
46 EmbeddedWorkerTestHelper
* helper
)
47 : ServiceWorkerDispatcherHost(process_id
, NULL
, resource_context
),
48 bad_messages_received_count_(0),
50 Init(context_wrapper
);
53 bool Send(IPC::Message
* message
) override
{ return helper_
->Send(message
); }
55 IPC::TestSink
* ipc_sink() { return helper_
->ipc_sink(); }
57 void ShutdownForBadMessage() override
{ ++bad_messages_received_count_
; }
59 int bad_messages_received_count_
;
62 EmbeddedWorkerTestHelper
* helper_
;
63 ~TestingServiceWorkerDispatcherHost() override
{}
66 class ServiceWorkerDispatcherHostTest
: public testing::Test
{
68 ServiceWorkerDispatcherHostTest()
69 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP
) {}
71 void SetUp() override
{
73 new EmbeddedWorkerTestHelper(base::FilePath(), kRenderProcessId
));
74 dispatcher_host_
= new TestingServiceWorkerDispatcherHost(
75 kRenderProcessId
, context_wrapper(), &resource_context_
, helper_
.get());
78 void TearDown() override
{ helper_
.reset(); }
80 ServiceWorkerContextCore
* context() { return helper_
->context(); }
81 ServiceWorkerContextWrapper
* context_wrapper() {
82 return helper_
->context_wrapper();
85 void SendRegister(int64 provider_id
, GURL pattern
, GURL worker_url
) {
86 dispatcher_host_
->OnMessageReceived(
87 ServiceWorkerHostMsg_RegisterServiceWorker(
88 -1, -1, provider_id
, pattern
, worker_url
));
89 base::RunLoop().RunUntilIdle();
92 void Register(int64 provider_id
,
95 uint32 expected_message
) {
96 SendRegister(provider_id
, pattern
, worker_url
);
97 EXPECT_TRUE(dispatcher_host_
->ipc_sink()->GetUniqueMessageMatching(
99 dispatcher_host_
->ipc_sink()->ClearMessages();
102 void SendUnregister(int64 provider_id
, int64 registration_id
) {
103 dispatcher_host_
->OnMessageReceived(
104 ServiceWorkerHostMsg_UnregisterServiceWorker(-1, -1, provider_id
,
106 base::RunLoop().RunUntilIdle();
109 void Unregister(int64 provider_id
,
110 int64 registration_id
,
111 uint32 expected_message
) {
112 SendUnregister(provider_id
, registration_id
);
113 EXPECT_TRUE(dispatcher_host_
->ipc_sink()->GetUniqueMessageMatching(
115 dispatcher_host_
->ipc_sink()->ClearMessages();
118 void SendGetRegistration(int64 provider_id
, GURL document_url
) {
119 dispatcher_host_
->OnMessageReceived(
120 ServiceWorkerHostMsg_GetRegistration(
121 -1, -1, provider_id
, document_url
));
122 base::RunLoop().RunUntilIdle();
125 void GetRegistration(int64 provider_id
,
127 uint32 expected_message
) {
128 SendGetRegistration(provider_id
, document_url
);
129 EXPECT_TRUE(dispatcher_host_
->ipc_sink()->GetUniqueMessageMatching(
131 dispatcher_host_
->ipc_sink()->ClearMessages();
134 void SendGetRegistrations(int64 provider_id
) {
135 dispatcher_host_
->OnMessageReceived(
136 ServiceWorkerHostMsg_GetRegistrations(-1, -1, provider_id
));
137 base::RunLoop().RunUntilIdle();
140 void GetRegistrations(int64 provider_id
, uint32 expected_message
) {
141 SendGetRegistrations(provider_id
);
142 EXPECT_TRUE(dispatcher_host_
->ipc_sink()->GetUniqueMessageMatching(
144 dispatcher_host_
->ipc_sink()->ClearMessages();
147 ServiceWorkerProviderHost
* CreateServiceWorkerProviderHost(int provider_id
) {
148 return new ServiceWorkerProviderHost(
149 kRenderProcessId
, kRenderFrameId
, provider_id
,
150 SERVICE_WORKER_PROVIDER_FOR_WINDOW
, context()->AsWeakPtr(),
151 dispatcher_host_
.get());
155 TestBrowserThreadBundle browser_thread_bundle_
;
156 content::MockResourceContext resource_context_
;
157 scoped_ptr
<EmbeddedWorkerTestHelper
> helper_
;
158 scoped_refptr
<TestingServiceWorkerDispatcherHost
> dispatcher_host_
;
161 class ServiceWorkerTestContentBrowserClient
: public TestContentBrowserClient
{
163 ServiceWorkerTestContentBrowserClient() {}
164 bool AllowServiceWorker(const GURL
& scope
,
165 const GURL
& first_party
,
166 content::ResourceContext
* context
,
167 int render_process_id
,
168 int render_frame_id
) override
{
173 TEST_F(ServiceWorkerDispatcherHostTest
,
174 Register_ContentSettingsDisallowsServiceWorker
) {
175 ServiceWorkerTestContentBrowserClient test_browser_client
;
176 ContentBrowserClient
* old_browser_client
=
177 SetBrowserClientForTesting(&test_browser_client
);
179 const int64 kProviderId
= 99; // Dummy value
180 scoped_ptr
<ServiceWorkerProviderHost
> host(
181 CreateServiceWorkerProviderHost(kProviderId
));
182 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
183 context()->AddProviderHost(host
.Pass());
185 Register(kProviderId
,
186 GURL("https://www.example.com/"),
187 GURL("https://www.example.com/bar"),
188 ServiceWorkerMsg_ServiceWorkerRegistrationError::ID
);
189 GetRegistration(kProviderId
,
190 GURL("https://www.example.com/"),
191 ServiceWorkerMsg_ServiceWorkerGetRegistrationError::ID
);
192 GetRegistrations(kProviderId
,
193 ServiceWorkerMsg_ServiceWorkerGetRegistrationsError::ID
);
195 // Add a registration into a live registration map so that Unregister() can
197 const int64 kRegistrationId
= 999; // Dummy value
198 scoped_refptr
<ServiceWorkerRegistration
> registration(
199 new ServiceWorkerRegistration(GURL("https://www.example.com/"),
200 kRegistrationId
, context()->AsWeakPtr()));
201 Unregister(kProviderId
, kRegistrationId
,
202 ServiceWorkerMsg_ServiceWorkerUnregistrationError::ID
);
204 SetBrowserClientForTesting(old_browser_client
);
207 TEST_F(ServiceWorkerDispatcherHostTest
, Register_HTTPS
) {
208 const int64 kProviderId
= 99; // Dummy value
209 scoped_ptr
<ServiceWorkerProviderHost
> host(
210 CreateServiceWorkerProviderHost(kProviderId
));
211 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
212 context()->AddProviderHost(host
.Pass());
214 Register(kProviderId
,
215 GURL("https://www.example.com/"),
216 GURL("https://www.example.com/bar"),
217 ServiceWorkerMsg_ServiceWorkerRegistered::ID
);
220 TEST_F(ServiceWorkerDispatcherHostTest
, Register_NonSecureTransportLocalhost
) {
221 const int64 kProviderId
= 99; // Dummy value
222 scoped_ptr
<ServiceWorkerProviderHost
> host(
223 CreateServiceWorkerProviderHost(kProviderId
));
224 host
->SetDocumentUrl(GURL("http://127.0.0.3:81/foo"));
225 context()->AddProviderHost(host
.Pass());
227 Register(kProviderId
,
228 GURL("http://127.0.0.3:81/bar"),
229 GURL("http://127.0.0.3:81/baz"),
230 ServiceWorkerMsg_ServiceWorkerRegistered::ID
);
233 TEST_F(ServiceWorkerDispatcherHostTest
, Register_InvalidScopeShouldFail
) {
234 const int64 kProviderId
= 99; // Dummy value
235 scoped_ptr
<ServiceWorkerProviderHost
> host(
236 CreateServiceWorkerProviderHost(kProviderId
));
237 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
238 context()->AddProviderHost(host
.Pass());
240 SendRegister(kProviderId
, GURL(""),
241 GURL("https://www.example.com/bar/hoge.js"));
242 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
245 TEST_F(ServiceWorkerDispatcherHostTest
, Register_InvalidScriptShouldFail
) {
246 const int64 kProviderId
= 99; // Dummy value
247 scoped_ptr
<ServiceWorkerProviderHost
> host(
248 CreateServiceWorkerProviderHost(kProviderId
));
249 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
250 context()->AddProviderHost(host
.Pass());
252 SendRegister(kProviderId
, GURL("https://www.example.com/bar/"), GURL(""));
253 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
256 TEST_F(ServiceWorkerDispatcherHostTest
, Register_NonSecureOriginShouldFail
) {
257 const int64 kProviderId
= 99; // Dummy value
258 scoped_ptr
<ServiceWorkerProviderHost
> host(
259 CreateServiceWorkerProviderHost(kProviderId
));
260 host
->SetDocumentUrl(GURL("http://www.example.com/foo"));
261 context()->AddProviderHost(host
.Pass());
263 SendRegister(kProviderId
,
264 GURL("http://www.example.com/"),
265 GURL("http://www.example.com/bar"));
266 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
269 TEST_F(ServiceWorkerDispatcherHostTest
, Register_CrossOriginShouldFail
) {
270 const int64 kProviderId
= 99; // Dummy value
271 scoped_ptr
<ServiceWorkerProviderHost
> host(
272 CreateServiceWorkerProviderHost(kProviderId
));
273 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
274 context()->AddProviderHost(host
.Pass());
276 // Script has a different host
277 SendRegister(kProviderId
,
278 GURL("https://www.example.com/"),
279 GURL("https://foo.example.com/bar"));
280 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
282 // Scope has a different host
283 SendRegister(kProviderId
,
284 GURL("https://foo.example.com/"),
285 GURL("https://www.example.com/bar"));
286 EXPECT_EQ(2, dispatcher_host_
->bad_messages_received_count_
);
288 // Script has a different port
289 SendRegister(kProviderId
,
290 GURL("https://www.example.com/"),
291 GURL("https://www.example.com:8080/bar"));
292 EXPECT_EQ(3, dispatcher_host_
->bad_messages_received_count_
);
294 // Scope has a different transport
295 SendRegister(kProviderId
,
296 GURL("wss://www.example.com/"),
297 GURL("https://www.example.com/bar"));
298 EXPECT_EQ(4, dispatcher_host_
->bad_messages_received_count_
);
300 // Script and scope have a different host but match each other
301 SendRegister(kProviderId
,
302 GURL("https://foo.example.com/"),
303 GURL("https://foo.example.com/bar"));
304 EXPECT_EQ(5, dispatcher_host_
->bad_messages_received_count_
);
306 // Script and scope URLs are invalid
307 SendRegister(kProviderId
,
310 EXPECT_EQ(6, dispatcher_host_
->bad_messages_received_count_
);
313 TEST_F(ServiceWorkerDispatcherHostTest
,
314 Register_FileSystemDocumentShouldFail
) {
315 const int64 kProviderId
= 99; // Dummy value
316 scoped_ptr
<ServiceWorkerProviderHost
> host(
317 CreateServiceWorkerProviderHost(kProviderId
));
318 host
->SetDocumentUrl(GURL("filesystem:https://www.example.com/temporary/a"));
319 context()->AddProviderHost(host
.Pass());
321 SendRegister(kProviderId
,
322 GURL("filesystem:https://www.example.com/temporary/"),
323 GURL("https://www.example.com/temporary/bar"));
324 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
326 SendRegister(kProviderId
,
327 GURL("https://www.example.com/temporary/"),
328 GURL("filesystem:https://www.example.com/temporary/bar"));
329 EXPECT_EQ(2, dispatcher_host_
->bad_messages_received_count_
);
331 SendRegister(kProviderId
,
332 GURL("filesystem:https://www.example.com/temporary/"),
333 GURL("filesystem:https://www.example.com/temporary/bar"));
334 EXPECT_EQ(3, dispatcher_host_
->bad_messages_received_count_
);
337 TEST_F(ServiceWorkerDispatcherHostTest
,
338 Register_FileSystemScriptOrScopeShouldFail
) {
339 const int64 kProviderId
= 99; // Dummy value
340 scoped_ptr
<ServiceWorkerProviderHost
> host(
341 CreateServiceWorkerProviderHost(kProviderId
));
342 host
->SetDocumentUrl(GURL("https://www.example.com/temporary/"));
343 context()->AddProviderHost(host
.Pass());
345 SendRegister(kProviderId
,
346 GURL("filesystem:https://www.example.com/temporary/"),
347 GURL("https://www.example.com/temporary/bar"));
348 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
350 SendRegister(kProviderId
,
351 GURL("https://www.example.com/temporary/"),
352 GURL("filesystem:https://www.example.com/temporary/bar"));
353 EXPECT_EQ(2, dispatcher_host_
->bad_messages_received_count_
);
355 SendRegister(kProviderId
,
356 GURL("filesystem:https://www.example.com/temporary/"),
357 GURL("filesystem:https://www.example.com/temporary/bar"));
358 EXPECT_EQ(3, dispatcher_host_
->bad_messages_received_count_
);
361 TEST_F(ServiceWorkerDispatcherHostTest
, EarlyContextDeletion
) {
362 helper_
->ShutdownContext();
364 // Let the shutdown reach the simulated IO thread.
365 base::RunLoop().RunUntilIdle();
370 ServiceWorkerMsg_ServiceWorkerRegistrationError::ID
);
373 TEST_F(ServiceWorkerDispatcherHostTest
, ProviderCreatedAndDestroyed
) {
374 const int kProviderId
= 1001; // Test with a value != kRenderProcessId.
376 dispatcher_host_
->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated(
377 kProviderId
, MSG_ROUTING_NONE
, SERVICE_WORKER_PROVIDER_FOR_WINDOW
));
378 EXPECT_TRUE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
380 // Two with the same ID should be seen as a bad message.
381 dispatcher_host_
->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated(
382 kProviderId
, MSG_ROUTING_NONE
, SERVICE_WORKER_PROVIDER_FOR_WINDOW
));
383 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
385 dispatcher_host_
->OnMessageReceived(
386 ServiceWorkerHostMsg_ProviderDestroyed(kProviderId
));
387 EXPECT_FALSE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
389 // Destroying an ID that does not exist warrants a bad message.
390 dispatcher_host_
->OnMessageReceived(
391 ServiceWorkerHostMsg_ProviderDestroyed(kProviderId
));
392 EXPECT_EQ(2, dispatcher_host_
->bad_messages_received_count_
);
394 // Deletion of the dispatcher_host should cause providers for that
395 // process to get deleted as well.
396 dispatcher_host_
->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated(
397 kProviderId
, MSG_ROUTING_NONE
, SERVICE_WORKER_PROVIDER_FOR_WINDOW
));
398 EXPECT_TRUE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
399 EXPECT_TRUE(dispatcher_host_
->HasOneRef());
400 dispatcher_host_
= NULL
;
401 EXPECT_FALSE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
404 TEST_F(ServiceWorkerDispatcherHostTest
, GetRegistration_SameOrigin
) {
405 const int64 kProviderId
= 99; // Dummy value
406 scoped_ptr
<ServiceWorkerProviderHost
> host(
407 CreateServiceWorkerProviderHost(kProviderId
));
408 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
409 context()->AddProviderHost(host
.Pass());
411 GetRegistration(kProviderId
,
412 GURL("https://www.example.com/"),
413 ServiceWorkerMsg_DidGetRegistration::ID
);
416 TEST_F(ServiceWorkerDispatcherHostTest
, GetRegistration_CrossOriginShouldFail
) {
417 const int64 kProviderId
= 99; // Dummy value
418 scoped_ptr
<ServiceWorkerProviderHost
> host(
419 CreateServiceWorkerProviderHost(kProviderId
));
420 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
421 context()->AddProviderHost(host
.Pass());
423 SendGetRegistration(kProviderId
, GURL("https://foo.example.com/"));
424 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
427 TEST_F(ServiceWorkerDispatcherHostTest
,
428 GetRegistration_InvalidScopeShouldFail
) {
429 const int64 kProviderId
= 99; // Dummy value
430 scoped_ptr
<ServiceWorkerProviderHost
> host(
431 CreateServiceWorkerProviderHost(kProviderId
));
432 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
433 context()->AddProviderHost(host
.Pass());
435 SendGetRegistration(kProviderId
, GURL(""));
436 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
439 TEST_F(ServiceWorkerDispatcherHostTest
,
440 GetRegistration_NonSecureOriginShouldFail
) {
441 const int64 kProviderId
= 99; // Dummy value
442 scoped_ptr
<ServiceWorkerProviderHost
> host(
443 CreateServiceWorkerProviderHost(kProviderId
));
444 host
->SetDocumentUrl(GURL("http://www.example.com/foo"));
445 context()->AddProviderHost(host
.Pass());
447 SendGetRegistration(kProviderId
, GURL("http://www.example.com/"));
448 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
451 TEST_F(ServiceWorkerDispatcherHostTest
, GetRegistration_EarlyContextDeletion
) {
452 helper_
->ShutdownContext();
454 // Let the shutdown reach the simulated IO thread.
455 base::RunLoop().RunUntilIdle();
459 ServiceWorkerMsg_ServiceWorkerGetRegistrationError::ID
);
462 TEST_F(ServiceWorkerDispatcherHostTest
, GetRegistrations_SecureOrigin
) {
463 const int64 kProviderId
= 99; // Dummy value
464 scoped_ptr
<ServiceWorkerProviderHost
> host(
465 CreateServiceWorkerProviderHost(kProviderId
));
466 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
467 context()->AddProviderHost(host
.Pass());
469 GetRegistrations(kProviderId
, ServiceWorkerMsg_DidGetRegistrations::ID
);
472 TEST_F(ServiceWorkerDispatcherHostTest
,
473 GetRegistrations_NonSecureOriginShouldFail
) {
474 const int64 kProviderId
= 99; // Dummy value
475 scoped_ptr
<ServiceWorkerProviderHost
> host(
476 CreateServiceWorkerProviderHost(kProviderId
));
477 host
->SetDocumentUrl(GURL("http://www.example.com/foo"));
478 context()->AddProviderHost(host
.Pass());
480 SendGetRegistrations(kProviderId
);
481 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
484 TEST_F(ServiceWorkerDispatcherHostTest
, GetRegistrations_EarlyContextDeletion
) {
485 helper_
->ShutdownContext();
487 // Let the shutdown reach the simulated IO thread.
488 base::RunLoop().RunUntilIdle();
490 GetRegistrations(-1, ServiceWorkerMsg_ServiceWorkerGetRegistrationsError::ID
);
493 TEST_F(ServiceWorkerDispatcherHostTest
, CleanupOnRendererCrash
) {
494 // Add a provider and worker.
495 const int64 kProviderId
= 99; // Dummy value
496 dispatcher_host_
->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated(
497 kProviderId
, MSG_ROUTING_NONE
, SERVICE_WORKER_PROVIDER_FOR_WINDOW
));
499 GURL pattern
= GURL("http://www.example.com/");
500 scoped_refptr
<ServiceWorkerRegistration
> registration(
501 new ServiceWorkerRegistration(pattern
,
503 helper_
->context()->AsWeakPtr()));
504 scoped_refptr
<ServiceWorkerVersion
> version(
505 new ServiceWorkerVersion(registration
.get(),
506 GURL("http://www.example.com/service_worker.js"),
508 helper_
->context()->AsWeakPtr()));
509 std::vector
<ServiceWorkerDatabase::ResourceRecord
> records
;
511 ServiceWorkerDatabase::ResourceRecord(10, version
->script_url(), 100));
512 version
->script_cache_map()->SetResources(records
);
514 // Make the registration findable via storage functions.
515 helper_
->context()->storage()->LazyInitialize(base::Bind(&base::DoNothing
));
516 base::RunLoop().RunUntilIdle();
518 ServiceWorkerStatusCode status
= SERVICE_WORKER_ERROR_ABORT
;
519 helper_
->context()->storage()->StoreRegistration(
522 base::Bind(&SaveStatusCallback
, &called
, &status
));
523 base::RunLoop().RunUntilIdle();
525 ASSERT_EQ(SERVICE_WORKER_OK
, status
);
527 helper_
->SimulateAddProcessToPattern(pattern
, kRenderProcessId
);
529 // Start up the worker.
530 status
= SERVICE_WORKER_ERROR_ABORT
;
531 version
->StartWorker(base::Bind(&SaveStatusCallback
, &called
, &status
));
532 base::RunLoop().RunUntilIdle();
535 EXPECT_EQ(SERVICE_WORKER_OK
, status
);
537 EXPECT_TRUE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
538 EXPECT_EQ(ServiceWorkerVersion::RUNNING
, version
->running_status());
540 // Simulate the render process crashing.
541 dispatcher_host_
->OnFilterRemoved();
543 // The dispatcher host should clean up the state from the process.
544 EXPECT_FALSE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
545 EXPECT_EQ(ServiceWorkerVersion::STOPPED
, version
->running_status());
547 // We should be able to hook up a new dispatcher host although the old object
548 // is not yet destroyed. This is what the browser does when reusing a crashed
550 scoped_refptr
<TestingServiceWorkerDispatcherHost
> new_dispatcher_host(
551 new TestingServiceWorkerDispatcherHost(kRenderProcessId
,
556 // To show the new dispatcher can operate, simulate provider creation. Since
557 // the old dispatcher cleaned up the old provider host, the new one won't
559 new_dispatcher_host
->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated(
560 kProviderId
, MSG_ROUTING_NONE
, SERVICE_WORKER_PROVIDER_FOR_WINDOW
));
561 EXPECT_EQ(0, new_dispatcher_host
->bad_messages_received_count_
);
564 } // namespace content