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 <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/macros.h" | 10 #include "base/macros.h" |
11 #include "base/profiler/scoped_tracker.h" | 11 #include "base/profiler/scoped_tracker.h" |
12 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
13 #include "base/thread_task_runner_handle.h" | |
13 #include "base/trace_event/trace_event.h" | 14 #include "base/trace_event/trace_event.h" |
14 #include "content/browser/bad_message.h" | 15 #include "content/browser/bad_message.h" |
15 #include "content/browser/message_port_message_filter.h" | 16 #include "content/browser/message_port_message_filter.h" |
16 #include "content/browser/message_port_service.h" | 17 #include "content/browser/message_port_service.h" |
17 #include "content/browser/service_worker/embedded_worker_registry.h" | 18 #include "content/browser/service_worker/embedded_worker_registry.h" |
19 #include "content/browser/service_worker/service_worker_client_utils.h" | |
18 #include "content/browser/service_worker/service_worker_context_core.h" | 20 #include "content/browser/service_worker/service_worker_context_core.h" |
19 #include "content/browser/service_worker/service_worker_context_wrapper.h" | 21 #include "content/browser/service_worker/service_worker_context_wrapper.h" |
20 #include "content/browser/service_worker/service_worker_handle.h" | 22 #include "content/browser/service_worker/service_worker_handle.h" |
21 #include "content/browser/service_worker/service_worker_navigation_handle_core.h " | 23 #include "content/browser/service_worker/service_worker_navigation_handle_core.h " |
22 #include "content/browser/service_worker/service_worker_registration.h" | 24 #include "content/browser/service_worker/service_worker_registration.h" |
23 #include "content/browser/service_worker/service_worker_registration_handle.h" | 25 #include "content/browser/service_worker/service_worker_registration_handle.h" |
24 #include "content/common/service_worker/embedded_worker_messages.h" | 26 #include "content/common/service_worker/embedded_worker_messages.h" |
25 #include "content/common/service_worker/service_worker_messages.h" | 27 #include "content/common/service_worker/service_worker_messages.h" |
26 #include "content/common/service_worker/service_worker_types.h" | 28 #include "content/common/service_worker/service_worker_types.h" |
27 #include "content/common/service_worker/service_worker_utils.h" | 29 #include "content/common/service_worker/service_worker_utils.h" |
(...skipping 16 matching lines...) Expand all Loading... | |
44 const char kShutdownErrorMessage[] = | 46 const char kShutdownErrorMessage[] = |
45 "The Service Worker system has shutdown."; | 47 "The Service Worker system has shutdown."; |
46 const char kUserDeniedPermissionMessage[] = | 48 const char kUserDeniedPermissionMessage[] = |
47 "The user denied permission to use Service Worker."; | 49 "The user denied permission to use Service Worker."; |
48 const char kInvalidStateErrorMessage[] = "The object is in an invalid state."; | 50 const char kInvalidStateErrorMessage[] = "The object is in an invalid state."; |
49 | 51 |
50 const uint32_t kFilteredMessageClasses[] = { | 52 const uint32_t kFilteredMessageClasses[] = { |
51 ServiceWorkerMsgStart, EmbeddedWorkerMsgStart, | 53 ServiceWorkerMsgStart, EmbeddedWorkerMsgStart, |
52 }; | 54 }; |
53 | 55 |
56 void RunSoon(const base::Closure& callback) { | |
57 if (!callback.is_null()) | |
58 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback); | |
59 } | |
60 | |
54 bool CanUnregisterServiceWorker(const GURL& document_url, | 61 bool CanUnregisterServiceWorker(const GURL& document_url, |
55 const GURL& pattern) { | 62 const GURL& pattern) { |
56 DCHECK(document_url.is_valid()); | 63 DCHECK(document_url.is_valid()); |
57 DCHECK(pattern.is_valid()); | 64 DCHECK(pattern.is_valid()); |
58 return document_url.GetOrigin() == pattern.GetOrigin() && | 65 return document_url.GetOrigin() == pattern.GetOrigin() && |
59 OriginCanAccessServiceWorkers(document_url) && | 66 OriginCanAccessServiceWorkers(document_url) && |
60 OriginCanAccessServiceWorkers(pattern); | 67 OriginCanAccessServiceWorkers(pattern); |
61 } | 68 } |
62 | 69 |
63 bool CanUpdateServiceWorker(const GURL& document_url, const GURL& pattern) { | 70 bool CanUpdateServiceWorker(const GURL& document_url, const GURL& pattern) { |
(...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
687 return; | 694 return; |
688 } | 695 } |
689 | 696 |
690 ServiceWorkerProviderHost* sender_provider_host = | 697 ServiceWorkerProviderHost* sender_provider_host = |
691 GetContext()->GetProviderHost(render_process_id_, provider_id); | 698 GetContext()->GetProviderHost(render_process_id_, provider_id); |
692 if (!sender_provider_host) { | 699 if (!sender_provider_host) { |
693 bad_message::ReceivedBadMessage(this, bad_message::SWDH_POST_MESSAGE); | 700 bad_message::ReceivedBadMessage(this, bad_message::SWDH_POST_MESSAGE); |
694 return; | 701 return; |
695 } | 702 } |
696 | 703 |
697 handle->version()->DispatchExtendableMessageEvent( | 704 for (const TransferredMessagePort& port : sent_message_ports) |
698 sender_provider_host, message, source_origin, sent_message_ports, | 705 MessagePortService::GetInstance()->HoldMessages(port.id); |
699 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); | 706 |
707 switch (sender_provider_host->provider_type()) { | |
708 case SERVICE_WORKER_PROVIDER_FOR_WINDOW: | |
709 case SERVICE_WORKER_PROVIDER_FOR_WORKER: | |
710 case SERVICE_WORKER_PROVIDER_FOR_SHARED_WORKER: | |
711 service_worker_client_utils::GetClient( | |
712 sender_provider_host, | |
713 base::Bind( | |
714 &ServiceWorkerDispatcherHost::DispatchExtendableMessageEvent< | |
715 ServiceWorkerClientInfo>, | |
716 this, make_scoped_refptr(handle->version()), message, | |
717 source_origin, sent_message_ports)); | |
718 break; | |
719 case SERVICE_WORKER_PROVIDER_FOR_CONTROLLER: | |
720 // TODO(nhiroki): Decrement a reference to ServiceWorkerHandle if starting | |
721 // worker fails (http://crbug.com/543198). | |
722 RunSoon(base::Bind( | |
723 &ServiceWorkerDispatcherHost::DispatchExtendableMessageEvent< | |
724 ServiceWorkerObjectInfo>, | |
725 this, make_scoped_refptr(handle->version()), message, source_origin, | |
726 sent_message_ports, | |
727 sender_provider_host->GetOrCreateServiceWorkerHandle( | |
728 sender_provider_host->running_hosted_version()))); | |
729 break; | |
730 case SERVICE_WORKER_PROVIDER_FOR_SANDBOXED_FRAME: | |
731 case SERVICE_WORKER_PROVIDER_UNKNOWN: | |
732 NOTREACHED() << sender_provider_host->provider_type(); | |
733 RunSoon(base::Bind( | |
734 &ServiceWorkerDispatcherHost::DidFailToDispatchExtendableMessageEvent, | |
735 this, sent_message_ports, SERVICE_WORKER_ERROR_FAILED)); | |
falken
2016/03/15 07:29:16
Should we bother handling this after NOTREACHED? P
nhiroki
2016/03/15 07:57:25
Good point. Yes, we don't have to handle the case.
| |
736 break; | |
737 } | |
700 } | 738 } |
701 | 739 |
702 void ServiceWorkerDispatcherHost::OnDeprecatedPostMessageToWorker( | 740 void ServiceWorkerDispatcherHost::OnDeprecatedPostMessageToWorker( |
703 int handle_id, | 741 int handle_id, |
704 const base::string16& message, | 742 const base::string16& message, |
705 const std::vector<TransferredMessagePort>& sent_message_ports) { | 743 const std::vector<TransferredMessagePort>& sent_message_ports) { |
706 TRACE_EVENT0("ServiceWorker", | 744 TRACE_EVENT0("ServiceWorker", |
707 "ServiceWorkerDispatcherHost::OnDeprecatedPostMessageToWorker"); | 745 "ServiceWorkerDispatcherHost::OnDeprecatedPostMessageToWorker"); |
708 if (!GetContext()) | 746 if (!GetContext()) |
709 return; | 747 return; |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
823 | 861 |
824 ServiceWorkerRegistrationObjectInfo info; | 862 ServiceWorkerRegistrationObjectInfo info; |
825 ServiceWorkerVersionAttributes attrs; | 863 ServiceWorkerVersionAttributes attrs; |
826 GetRegistrationObjectInfoAndVersionAttributes( | 864 GetRegistrationObjectInfoAndVersionAttributes( |
827 provider_host->AsWeakPtr(), registration, &info, &attrs); | 865 provider_host->AsWeakPtr(), registration, &info, &attrs); |
828 | 866 |
829 Send(new ServiceWorkerMsg_AssociateRegistration(kDocumentMainThreadId, | 867 Send(new ServiceWorkerMsg_AssociateRegistration(kDocumentMainThreadId, |
830 provider_id, info, attrs)); | 868 provider_id, info, attrs)); |
831 } | 869 } |
832 | 870 |
871 template <typename SourceInfo> | |
872 void ServiceWorkerDispatcherHost::DispatchExtendableMessageEvent( | |
873 scoped_refptr<ServiceWorkerVersion> worker, | |
874 const base::string16& message, | |
875 const url::Origin& source_origin, | |
876 const std::vector<TransferredMessagePort>& sent_message_ports, | |
877 const SourceInfo& source_info) { | |
878 if (!source_info.IsValid()) { | |
879 DidFailToDispatchExtendableMessageEvent(sent_message_ports, | |
880 SERVICE_WORKER_ERROR_FAILED); | |
881 return; | |
882 } | |
883 worker->RunAfterStartWorker( | |
884 base::Bind(&ServiceWorkerDispatcherHost:: | |
885 DispatchExtendableMessageEventAfterStartWorker, | |
886 this, worker, message, source_origin, sent_message_ports, | |
887 ExtendableMessageEventSource(source_info)), | |
888 base::Bind( | |
889 &ServiceWorkerDispatcherHost::DidFailToDispatchExtendableMessageEvent, | |
890 this, sent_message_ports)); | |
891 } | |
892 | |
893 void ServiceWorkerDispatcherHost:: | |
894 DispatchExtendableMessageEventAfterStartWorker( | |
895 scoped_refptr<ServiceWorkerVersion> worker, | |
896 const base::string16& message, | |
897 const url::Origin& source_origin, | |
898 const std::vector<TransferredMessagePort>& sent_message_ports, | |
899 const ExtendableMessageEventSource& source) { | |
900 int request_id = | |
901 worker->StartRequest(ServiceWorkerMetrics::EventType::MESSAGE, | |
902 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); | |
903 | |
904 MessagePortMessageFilter* filter = | |
905 worker->embedded_worker()->message_port_message_filter(); | |
906 std::vector<int> new_routing_ids; | |
907 filter->UpdateMessagePortsWithNewRoutes(sent_message_ports, &new_routing_ids); | |
908 | |
909 ServiceWorkerMsg_ExtendableMessageEvent_Params params; | |
910 params.message = message; | |
911 params.source_origin = source_origin; | |
912 params.message_ports = sent_message_ports; | |
913 params.new_routing_ids = new_routing_ids; | |
914 params.source = source; | |
915 | |
916 // Hide the client url if the client has a unique origin. | |
917 if (source_origin.unique()) { | |
918 if (params.source.client_info.IsValid()) | |
919 params.source.client_info.url = GURL(); | |
920 else | |
921 params.source.service_worker_info.url = GURL(); | |
922 } | |
923 | |
924 worker->DispatchSimpleEvent< | |
925 ServiceWorkerHostMsg_ExtendableMessageEventFinished>( | |
926 request_id, ServiceWorkerMsg_ExtendableMessageEvent(request_id, params)); | |
927 } | |
928 | |
929 void ServiceWorkerDispatcherHost::DidFailToDispatchExtendableMessageEvent( | |
930 const std::vector<TransferredMessagePort>& sent_message_ports, | |
931 ServiceWorkerStatusCode status) { | |
932 // Transfering the message ports failed, so destroy the ports. | |
933 for (const TransferredMessagePort& port : sent_message_ports) | |
934 MessagePortService::GetInstance()->ClosePort(port.id); | |
935 } | |
936 | |
833 ServiceWorkerRegistrationHandle* | 937 ServiceWorkerRegistrationHandle* |
834 ServiceWorkerDispatcherHost::FindRegistrationHandle(int provider_id, | 938 ServiceWorkerDispatcherHost::FindRegistrationHandle(int provider_id, |
835 int64_t registration_id) { | 939 int64_t registration_id) { |
836 for (RegistrationHandleMap::iterator iter(®istration_handles_); | 940 for (RegistrationHandleMap::iterator iter(®istration_handles_); |
837 !iter.IsAtEnd(); iter.Advance()) { | 941 !iter.IsAtEnd(); iter.Advance()) { |
838 ServiceWorkerRegistrationHandle* handle = iter.GetCurrentValue(); | 942 ServiceWorkerRegistrationHandle* handle = iter.GetCurrentValue(); |
839 if (handle->provider_id() == provider_id && | 943 if (handle->provider_id() == provider_id && |
840 handle->registration()->id() == registration_id) { | 944 handle->registration()->id() == registration_id) { |
841 return handle; | 945 return handle; |
842 } | 946 } |
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1288 if (!handle) { | 1392 if (!handle) { |
1289 bad_message::ReceivedBadMessage(this, | 1393 bad_message::ReceivedBadMessage(this, |
1290 bad_message::SWDH_TERMINATE_BAD_HANDLE); | 1394 bad_message::SWDH_TERMINATE_BAD_HANDLE); |
1291 return; | 1395 return; |
1292 } | 1396 } |
1293 handle->version()->StopWorker( | 1397 handle->version()->StopWorker( |
1294 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); | 1398 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); |
1295 } | 1399 } |
1296 | 1400 |
1297 } // namespace content | 1401 } // namespace content |
OLD | NEW |