OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/service_worker/service_worker_dispatcher_host.h" | 5 #include "content/browser/service_worker/service_worker_dispatcher_host.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
12 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" |
13 #include "base/memory/ptr_util.h" | 13 #include "base/memory/ptr_util.h" |
14 #include "base/run_loop.h" | 14 #include "base/run_loop.h" |
15 #include "base/test/simple_test_tick_clock.h" | 15 #include "base/test/simple_test_tick_clock.h" |
16 #include "base/time/time.h" | 16 #include "base/time/time.h" |
17 #include "content/browser/browser_thread_impl.h" | 17 #include "content/browser/browser_thread_impl.h" |
18 #include "content/browser/service_worker/embedded_worker_instance.h" | 18 #include "content/browser/service_worker/embedded_worker_instance.h" |
19 #include "content/browser/service_worker/embedded_worker_registry.h" | 19 #include "content/browser/service_worker/embedded_worker_registry.h" |
20 #include "content/browser/service_worker/embedded_worker_status.h" | 20 #include "content/browser/service_worker/embedded_worker_status.h" |
21 #include "content/browser/service_worker/embedded_worker_test_helper.h" | 21 #include "content/browser/service_worker/embedded_worker_test_helper.h" |
22 #include "content/browser/service_worker/service_worker_context_core.h" | 22 #include "content/browser/service_worker/service_worker_context_core.h" |
23 #include "content/browser/service_worker/service_worker_context_wrapper.h" | 23 #include "content/browser/service_worker/service_worker_context_wrapper.h" |
24 #include "content/browser/service_worker/service_worker_handle.h" | 24 #include "content/browser/service_worker/service_worker_handle.h" |
25 #include "content/browser/service_worker/service_worker_navigation_handle_core.h " | |
25 #include "content/browser/service_worker/service_worker_test_utils.h" | 26 #include "content/browser/service_worker/service_worker_test_utils.h" |
26 #include "content/common/service_worker/embedded_worker_messages.h" | 27 #include "content/common/service_worker/embedded_worker_messages.h" |
27 #include "content/common/service_worker/service_worker_messages.h" | 28 #include "content/common/service_worker/service_worker_messages.h" |
28 #include "content/common/service_worker/service_worker_types.h" | 29 #include "content/common/service_worker/service_worker_types.h" |
29 #include "content/common/service_worker/service_worker_utils.h" | 30 #include "content/common/service_worker/service_worker_utils.h" |
31 #include "content/public/common/browser_side_navigation_policy.h" | |
30 #include "content/public/common/content_switches.h" | 32 #include "content/public/common/content_switches.h" |
31 #include "content/public/test/mock_resource_context.h" | 33 #include "content/public/test/mock_resource_context.h" |
32 #include "content/public/test/test_browser_thread_bundle.h" | 34 #include "content/public/test/test_browser_thread_bundle.h" |
33 #include "content/test/test_content_browser_client.h" | 35 #include "content/test/test_content_browser_client.h" |
34 #include "testing/gtest/include/gtest/gtest.h" | 36 #include "testing/gtest/include/gtest/gtest.h" |
35 | 37 |
36 namespace content { | 38 namespace content { |
37 | 39 |
38 namespace { | 40 namespace { |
39 | 41 |
40 static void SaveStatusCallback(bool* called, | 42 static void SaveStatusCallback(bool* called, |
41 ServiceWorkerStatusCode* out, | 43 ServiceWorkerStatusCode* out, |
42 ServiceWorkerStatusCode status) { | 44 ServiceWorkerStatusCode status) { |
43 *called = true; | 45 *called = true; |
44 *out = status; | 46 *out = status; |
45 } | 47 } |
46 | 48 |
47 void SetUpDummyMessagePort(std::vector<MessagePort>* ports) { | 49 void SetUpDummyMessagePort(std::vector<MessagePort>* ports) { |
48 // Let the other end of the pipe close. | 50 // Let the other end of the pipe close. |
49 mojo::MessagePipe pipe; | 51 mojo::MessagePipe pipe; |
50 ports->push_back(MessagePort(std::move(pipe.handle0))); | 52 ports->push_back(MessagePort(std::move(pipe.handle0))); |
51 } | 53 } |
52 | 54 |
55 struct RemoteProviderInfo { | |
56 mojom::ServiceWorkerProviderHostAssociatedPtr host_ptr; | |
57 mojom::ServiceWorkerProviderAssociatedRequest client_request; | |
58 }; | |
59 | |
60 RemoteProviderInfo SetupProviderHostInfoPtrs( | |
61 ServiceWorkerProviderHostInfo* host_info) { | |
62 RemoteProviderInfo remote_info; | |
63 mojom::ServiceWorkerProviderAssociatedPtr browser_side_client_ptr; | |
64 remote_info.client_request = | |
65 mojo::MakeIsolatedRequest(&browser_side_client_ptr); | |
66 host_info->host_request = mojo::MakeIsolatedRequest(&remote_info.host_ptr); | |
67 host_info->client_ptr_info = browser_side_client_ptr.PassInterface(); | |
68 EXPECT_TRUE(host_info->host_request.is_pending()); | |
69 EXPECT_TRUE(host_info->client_ptr_info.is_valid()); | |
70 EXPECT_TRUE(remote_info.host_ptr.is_bound()); | |
71 EXPECT_TRUE(remote_info.client_request.is_pending()); | |
72 return remote_info; | |
73 } | |
74 | |
75 std::unique_ptr<ServiceWorkerNavigationHandleCore> CreateNavigationHandleCore( | |
76 ServiceWorkerContextWrapper* context_wrapper) { | |
77 std::unique_ptr<ServiceWorkerNavigationHandleCore> navigation_handle_core; | |
78 BrowserThread::PostTaskAndReplyWithResult( | |
79 BrowserThread::UI, FROM_HERE, | |
80 base::Bind( | |
81 [](ServiceWorkerContextWrapper* wrapper) { | |
82 return base::MakeUnique<ServiceWorkerNavigationHandleCore>(nullptr, | |
83 wrapper); | |
84 }, | |
85 context_wrapper), | |
86 base::Bind( | |
87 [](std::unique_ptr<ServiceWorkerNavigationHandleCore>* dest, | |
88 std::unique_ptr<ServiceWorkerNavigationHandleCore> src) { | |
89 *dest = std::move(src); | |
90 }, | |
91 &navigation_handle_core)); | |
92 base::RunLoop().RunUntilIdle(); | |
93 return navigation_handle_core; | |
94 } | |
95 | |
53 } // namespace | 96 } // namespace |
54 | 97 |
55 static const int kRenderFrameId = 1; | 98 static const int kRenderFrameId = 1; |
56 | 99 |
57 class TestingServiceWorkerDispatcherHost : public ServiceWorkerDispatcherHost { | 100 class TestingServiceWorkerDispatcherHost : public ServiceWorkerDispatcherHost { |
58 public: | 101 public: |
59 TestingServiceWorkerDispatcherHost( | 102 TestingServiceWorkerDispatcherHost( |
60 int process_id, | 103 int process_id, |
61 ServiceWorkerContextWrapper* context_wrapper, | 104 ServiceWorkerContextWrapper* context_wrapper, |
62 ResourceContext* resource_context, | 105 ResourceContext* resource_context, |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
161 int embedded_worker_id) { | 204 int embedded_worker_id) { |
162 dispatcher_host_->OnSetHostedVersionId(provider_id, version_id, | 205 dispatcher_host_->OnSetHostedVersionId(provider_id, version_id, |
163 embedded_worker_id); | 206 embedded_worker_id); |
164 } | 207 } |
165 | 208 |
166 void SendProviderCreated(ServiceWorkerProviderType type, | 209 void SendProviderCreated(ServiceWorkerProviderType type, |
167 const GURL& pattern) { | 210 const GURL& pattern) { |
168 const int64_t kProviderId = 99; | 211 const int64_t kProviderId = 99; |
169 ServiceWorkerProviderHostInfo info(kProviderId, MSG_ROUTING_NONE, type, | 212 ServiceWorkerProviderHostInfo info(kProviderId, MSG_ROUTING_NONE, type, |
170 true /* is_parent_frame_secure */); | 213 true /* is_parent_frame_secure */); |
214 remote_endpoint_.BindWithProviderHostInfo(&info); | |
215 | |
171 dispatcher_host_->OnProviderCreated(std::move(info)); | 216 dispatcher_host_->OnProviderCreated(std::move(info)); |
172 helper_->SimulateAddProcessToPattern(pattern, | 217 helper_->SimulateAddProcessToPattern(pattern, |
173 helper_->mock_render_process_id()); | 218 helper_->mock_render_process_id()); |
174 provider_host_ = context()->GetProviderHost( | 219 provider_host_ = context()->GetProviderHost( |
175 helper_->mock_render_process_id(), kProviderId); | 220 helper_->mock_render_process_id(), kProviderId); |
176 } | 221 } |
177 | 222 |
178 void SendRegister(int64_t provider_id, GURL pattern, GURL worker_url) { | 223 void SendRegister(int64_t provider_id, GURL pattern, GURL worker_url) { |
179 dispatcher_host_->OnMessageReceived( | 224 dispatcher_host_->OnMessageReceived( |
180 ServiceWorkerHostMsg_RegisterServiceWorker( | 225 ServiceWorkerHostMsg_RegisterServiceWorker( |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
246 const ServiceWorkerDispatcherHost::StatusCallback& callback) { | 291 const ServiceWorkerDispatcherHost::StatusCallback& callback) { |
247 dispatcher_host_->DispatchExtendableMessageEvent( | 292 dispatcher_host_->DispatchExtendableMessageEvent( |
248 std::move(worker), message, source_origin, sent_message_ports, | 293 std::move(worker), message, source_origin, sent_message_ports, |
249 sender_provider_host, callback); | 294 sender_provider_host, callback); |
250 } | 295 } |
251 | 296 |
252 std::unique_ptr<ServiceWorkerProviderHost> CreateServiceWorkerProviderHost( | 297 std::unique_ptr<ServiceWorkerProviderHost> CreateServiceWorkerProviderHost( |
253 int provider_id) { | 298 int provider_id) { |
254 return CreateProviderHostWithDispatcherHost( | 299 return CreateProviderHostWithDispatcherHost( |
255 helper_->mock_render_process_id(), provider_id, context()->AsWeakPtr(), | 300 helper_->mock_render_process_id(), provider_id, context()->AsWeakPtr(), |
256 kRenderFrameId, dispatcher_host_.get()); | 301 kRenderFrameId, dispatcher_host_.get(), &remote_endpoint_); |
257 } | 302 } |
258 | 303 |
259 TestBrowserThreadBundle browser_thread_bundle_; | 304 TestBrowserThreadBundle browser_thread_bundle_; |
260 content::MockResourceContext resource_context_; | 305 content::MockResourceContext resource_context_; |
261 std::unique_ptr<EmbeddedWorkerTestHelper> helper_; | 306 std::unique_ptr<EmbeddedWorkerTestHelper> helper_; |
262 scoped_refptr<TestingServiceWorkerDispatcherHost> dispatcher_host_; | 307 scoped_refptr<TestingServiceWorkerDispatcherHost> dispatcher_host_; |
263 scoped_refptr<ServiceWorkerRegistration> registration_; | 308 scoped_refptr<ServiceWorkerRegistration> registration_; |
264 scoped_refptr<ServiceWorkerVersion> version_; | 309 scoped_refptr<ServiceWorkerVersion> version_; |
265 ServiceWorkerProviderHost* provider_host_; | 310 ServiceWorkerProviderHost* provider_host_; |
311 ServiceWorkerRemoteProviderEndpoint remote_endpoint_; | |
266 }; | 312 }; |
267 | 313 |
268 class ServiceWorkerTestContentBrowserClient : public TestContentBrowserClient { | 314 class ServiceWorkerTestContentBrowserClient : public TestContentBrowserClient { |
269 public: | 315 public: |
270 ServiceWorkerTestContentBrowserClient() {} | 316 ServiceWorkerTestContentBrowserClient() {} |
271 bool AllowServiceWorker( | 317 bool AllowServiceWorker( |
272 const GURL& scope, | 318 const GURL& scope, |
273 const GURL& first_party, | 319 const GURL& first_party, |
274 content::ResourceContext* context, | 320 content::ResourceContext* context, |
275 const base::Callback<WebContents*(void)>& wc_getter) override { | 321 const base::Callback<WebContents*(void)>& wc_getter) override { |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
502 // Let the shutdown reach the simulated IO thread. | 548 // Let the shutdown reach the simulated IO thread. |
503 base::RunLoop().RunUntilIdle(); | 549 base::RunLoop().RunUntilIdle(); |
504 | 550 |
505 Register(-1, | 551 Register(-1, |
506 GURL(), | 552 GURL(), |
507 GURL(), | 553 GURL(), |
508 ServiceWorkerMsg_ServiceWorkerRegistrationError::ID); | 554 ServiceWorkerMsg_ServiceWorkerRegistrationError::ID); |
509 } | 555 } |
510 | 556 |
511 TEST_F(ServiceWorkerDispatcherHostTest, ProviderCreatedAndDestroyed) { | 557 TEST_F(ServiceWorkerDispatcherHostTest, ProviderCreatedAndDestroyed) { |
512 const int kProviderId = 1001; | 558 const int kProviderId = (IsBrowserSideNavigationEnabled() ? -2 : 1001); |
falken
2017/05/30 04:12:32
Can you comment that in the PlzNavigate case it mu
shimazu
2017/05/30 07:24:35
Done.
| |
513 int process_id = helper_->mock_render_process_id(); | 559 int process_id = helper_->mock_render_process_id(); |
514 | 560 |
515 dispatcher_host_->OnProviderCreated(ServiceWorkerProviderHostInfo( | 561 // Setup ServiceWorkerProviderHostInfo. |
516 kProviderId, MSG_ROUTING_NONE, SERVICE_WORKER_PROVIDER_FOR_WINDOW, | 562 ServiceWorkerProviderHostInfo host_info_1(kProviderId, 1 /* route_id */, |
517 true /* is_parent_frame_secure */)); | 563 SERVICE_WORKER_PROVIDER_FOR_WINDOW, |
564 true /* is_parent_frame_secure */); | |
565 ServiceWorkerProviderHostInfo host_info_2(kProviderId, 1 /* route_id */, | |
566 SERVICE_WORKER_PROVIDER_FOR_WINDOW, | |
567 true /* is_parent_frame_secure */); | |
568 ServiceWorkerProviderHostInfo host_info_3(kProviderId, 1 /* route_id */, | |
569 SERVICE_WORKER_PROVIDER_FOR_WINDOW, | |
570 true /* is_parent_frame_secure */); | |
571 RemoteProviderInfo remote_info_1 = SetupProviderHostInfoPtrs(&host_info_1); | |
572 RemoteProviderInfo remote_info_2 = SetupProviderHostInfoPtrs(&host_info_2); | |
573 RemoteProviderInfo remote_info_3 = SetupProviderHostInfoPtrs(&host_info_3); | |
574 | |
575 // PlzNavigate | |
576 std::unique_ptr<ServiceWorkerNavigationHandleCore> navigation_handle_core; | |
577 if (IsBrowserSideNavigationEnabled()) { | |
578 navigation_handle_core = | |
579 CreateNavigationHandleCore(helper_->context_wrapper()); | |
580 ASSERT_TRUE(navigation_handle_core); | |
581 // ProviderHost should be created before OnProviderCreated. | |
582 navigation_handle_core->DidPreCreateProviderHost( | |
583 ServiceWorkerProviderHost::PreCreateNavigationHost( | |
584 helper_->context()->AsWeakPtr(), true /* are_ancestors_secure */, | |
585 base::Callback<WebContents*(void)>())); | |
586 } | |
587 | |
588 dispatcher_host_->OnProviderCreated(std::move(host_info_1)); | |
518 EXPECT_TRUE(context()->GetProviderHost(process_id, kProviderId)); | 589 EXPECT_TRUE(context()->GetProviderHost(process_id, kProviderId)); |
519 | 590 |
520 // Two with the same ID should be seen as a bad message. | 591 // Two with the same ID should be seen as a bad message. |
521 dispatcher_host_->OnProviderCreated(ServiceWorkerProviderHostInfo( | 592 dispatcher_host_->OnProviderCreated(std::move(host_info_2)); |
522 kProviderId, MSG_ROUTING_NONE, SERVICE_WORKER_PROVIDER_FOR_WINDOW, | |
523 true /* is_parent_frame_secure */)); | |
524 EXPECT_EQ(1, dispatcher_host_->bad_messages_received_count_); | 593 EXPECT_EQ(1, dispatcher_host_->bad_messages_received_count_); |
525 | 594 |
526 dispatcher_host_->OnProviderDestroyed(kProviderId); | 595 // Releasing the interface pointer destroys the counterpart. |
596 remote_info_1.host_ptr.reset(); | |
597 base::RunLoop().RunUntilIdle(); | |
527 EXPECT_FALSE(context()->GetProviderHost(process_id, kProviderId)); | 598 EXPECT_FALSE(context()->GetProviderHost(process_id, kProviderId)); |
528 | 599 |
529 // Destroying an ID that does not exist warrants a bad message. | 600 // PlzNavigate |
530 dispatcher_host_->OnProviderDestroyed(kProviderId); | 601 // Prepare another navigation handle to create another provider host. |
531 EXPECT_EQ(2, dispatcher_host_->bad_messages_received_count_); | 602 if (IsBrowserSideNavigationEnabled()) { |
603 navigation_handle_core = | |
604 CreateNavigationHandleCore(helper_->context_wrapper()); | |
605 ASSERT_TRUE(navigation_handle_core); | |
606 // ProviderHost should be created before OnProviderCreated. | |
607 navigation_handle_core->DidPreCreateProviderHost( | |
608 ServiceWorkerProviderHost::PreCreateNavigationHost( | |
609 helper_->context()->AsWeakPtr(), true /* are_ancestors_secure */, | |
610 base::Callback<WebContents*(void)>())); | |
611 } | |
532 | 612 |
533 // Deletion of the dispatcher_host should cause providers for that | 613 // Deletion of the dispatcher_host should cause providers for that |
534 // process to get deleted as well. | 614 // process to get deleted as well. |
535 dispatcher_host_->OnProviderCreated(ServiceWorkerProviderHostInfo( | 615 dispatcher_host_->OnProviderCreated(std::move(host_info_3)); |
536 kProviderId, MSG_ROUTING_NONE, SERVICE_WORKER_PROVIDER_FOR_WINDOW, | |
537 true /* is_parent_frame_secure */)); | |
538 EXPECT_TRUE(context()->GetProviderHost(process_id, kProviderId)); | 616 EXPECT_TRUE(context()->GetProviderHost(process_id, kProviderId)); |
539 EXPECT_TRUE(dispatcher_host_->HasOneRef()); | 617 EXPECT_TRUE(dispatcher_host_->HasOneRef()); |
540 dispatcher_host_ = nullptr; | 618 dispatcher_host_ = nullptr; |
541 EXPECT_FALSE(context()->GetProviderHost(process_id, kProviderId)); | 619 EXPECT_FALSE(context()->GetProviderHost(process_id, kProviderId)); |
542 } | 620 } |
543 | 621 |
544 TEST_F(ServiceWorkerDispatcherHostTest, GetRegistration_SameOrigin) { | 622 TEST_F(ServiceWorkerDispatcherHostTest, GetRegistration_SameOrigin) { |
545 const int64_t kProviderId = 99; // Dummy value | 623 const int64_t kProviderId = 99; // Dummy value |
546 std::unique_ptr<ServiceWorkerProviderHost> host( | 624 std::unique_ptr<ServiceWorkerProviderHost> host( |
547 CreateServiceWorkerProviderHost(kProviderId)); | 625 CreateServiceWorkerProviderHost(kProviderId)); |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
662 // We should be able to hook up a new dispatcher host although the old object | 740 // We should be able to hook up a new dispatcher host although the old object |
663 // is not yet destroyed. This is what the browser does when reusing a crashed | 741 // is not yet destroyed. This is what the browser does when reusing a crashed |
664 // render process. | 742 // render process. |
665 scoped_refptr<TestingServiceWorkerDispatcherHost> new_dispatcher_host( | 743 scoped_refptr<TestingServiceWorkerDispatcherHost> new_dispatcher_host( |
666 new TestingServiceWorkerDispatcherHost( | 744 new TestingServiceWorkerDispatcherHost( |
667 process_id, context_wrapper(), &resource_context_, helper_.get())); | 745 process_id, context_wrapper(), &resource_context_, helper_.get())); |
668 | 746 |
669 // To show the new dispatcher can operate, simulate provider creation. Since | 747 // To show the new dispatcher can operate, simulate provider creation. Since |
670 // the old dispatcher cleaned up the old provider host, the new one won't | 748 // the old dispatcher cleaned up the old provider host, the new one won't |
671 // complain. | 749 // complain. |
672 new_dispatcher_host->OnProviderCreated(ServiceWorkerProviderHostInfo( | 750 ServiceWorkerProviderHostInfo host_info(provider_id, MSG_ROUTING_NONE, |
673 provider_id, MSG_ROUTING_NONE, SERVICE_WORKER_PROVIDER_FOR_WINDOW, | 751 SERVICE_WORKER_PROVIDER_FOR_WINDOW, |
674 true /* is_parent_frame_secure */)); | 752 true /* is_parent_frame_secure */); |
753 ServiceWorkerRemoteProviderEndpoint remote_endpoint; | |
754 remote_endpoint.BindWithProviderHostInfo(&host_info); | |
755 new_dispatcher_host->OnProviderCreated(std::move(host_info)); | |
675 EXPECT_EQ(0, new_dispatcher_host->bad_messages_received_count_); | 756 EXPECT_EQ(0, new_dispatcher_host->bad_messages_received_count_); |
676 } | 757 } |
677 | 758 |
678 TEST_F(ServiceWorkerDispatcherHostTest, DispatchExtendableMessageEvent) { | 759 TEST_F(ServiceWorkerDispatcherHostTest, DispatchExtendableMessageEvent) { |
679 GURL pattern = GURL("http://www.example.com/"); | 760 GURL pattern = GURL("http://www.example.com/"); |
680 GURL script_url = GURL("http://www.example.com/service_worker.js"); | 761 GURL script_url = GURL("http://www.example.com/service_worker.js"); |
681 | 762 |
682 SendProviderCreated(SERVICE_WORKER_PROVIDER_FOR_CONTROLLER, pattern); | 763 SendProviderCreated(SERVICE_WORKER_PROVIDER_FOR_CONTROLLER, pattern); |
683 SetUpRegistration(pattern, script_url); | 764 SetUpRegistration(pattern, script_url); |
684 | 765 |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
833 const int kFetchEventId = 91; // Dummy value | 914 const int kFetchEventId = 91; // Dummy value |
834 dispatcher_host_->OnMessageReceived(ServiceWorkerHostMsg_FetchEventResponse( | 915 dispatcher_host_->OnMessageReceived(ServiceWorkerHostMsg_FetchEventResponse( |
835 version_->embedded_worker()->embedded_worker_id(), kFetchEventId, | 916 version_->embedded_worker()->embedded_worker_id(), kFetchEventId, |
836 ServiceWorkerResponse(), base::Time::Now())); | 917 ServiceWorkerResponse(), base::Time::Now())); |
837 | 918 |
838 base::RunLoop().RunUntilIdle(); | 919 base::RunLoop().RunUntilIdle(); |
839 EXPECT_EQ(0, dispatcher_host_->bad_messages_received_count_); | 920 EXPECT_EQ(0, dispatcher_host_->bad_messages_received_count_); |
840 } | 921 } |
841 | 922 |
842 } // namespace content | 923 } // namespace content |
OLD | NEW |