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_version.h" | 5 #include "content/browser/service_worker/service_worker_version.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
9 #include "base/strings/string16.h" | 9 #include "base/strings/string16.h" |
10 #include "content/browser/message_port_message_filter.h" | 10 #include "content/browser/message_port_message_filter.h" |
11 #include "content/browser/message_port_service.h" | 11 #include "content/browser/message_port_service.h" |
12 #include "content/browser/service_worker/embedded_worker_instance.h" | 12 #include "content/browser/service_worker/embedded_worker_instance.h" |
13 #include "content/browser/service_worker/embedded_worker_registry.h" | 13 #include "content/browser/service_worker/embedded_worker_registry.h" |
14 #include "content/browser/service_worker/service_worker_context_core.h" | 14 #include "content/browser/service_worker/service_worker_context_core.h" |
15 #include "content/browser/service_worker/service_worker_registration.h" | 15 #include "content/browser/service_worker/service_worker_registration.h" |
16 #include "content/browser/service_worker/service_worker_utils.h" | 16 #include "content/browser/service_worker/service_worker_utils.h" |
17 #include "content/common/service_worker/service_worker_messages.h" | 17 #include "content/common/service_worker/service_worker_messages.h" |
18 #include "content/public/browser/browser_thread.h" | 18 #include "content/public/browser/browser_thread.h" |
19 #include "content/public/common/content_switches.h" | 19 #include "content/public/common/content_switches.h" |
20 | 20 |
21 namespace content { | 21 namespace content { |
22 | 22 |
23 typedef ServiceWorkerVersion::StatusCallback StatusCallback; | 23 typedef ServiceWorkerVersion::StatusCallback StatusCallback; |
24 typedef ServiceWorkerVersion::MessageCallback MessageCallback; | 24 typedef ServiceWorkerVersion::MessageCallback MessageCallback; |
25 | 25 |
26 class ServiceWorkerVersion::GetClientInfoCallback { | |
27 public: | |
28 GetClientInfoCallback(int request_id) | |
29 : request_id_(request_id) {} | |
30 void add(int client_request_id, int client_id) { | |
nhiroki
2014/12/08 05:45:09
The first letter of function names should be capit
Kunihiko Sakamoto
2014/12/08 06:43:18
Done.
| |
31 pending_requests_[client_request_id] = client_id; | |
32 } | |
33 void success(int client_request_id, const ServiceWorkerClientInfo& info) { | |
34 auto found = pending_requests_.find(client_request_id); | |
35 DCHECK(found != pending_requests_.end()); | |
36 clients_.push_back(info); | |
37 clients_.back().client_id = found->second; | |
38 pending_requests_.erase(found); | |
39 } | |
40 void error(int client_request_id) { cancel(client_request_id); } | |
41 void cancel(int client_request_id) { | |
42 auto found = pending_requests_.find(client_request_id); | |
43 DCHECK(found != pending_requests_.end()); | |
44 pending_requests_.erase(found); | |
45 } | |
46 int request_id() { return request_id_; } | |
47 bool has_pending_requests() { return !pending_requests_.empty(); } | |
48 const std::vector<ServiceWorkerClientInfo>& clients() { return clients_; } | |
49 | |
50 static void ClearCallbacks(IDMap<GetClientInfoCallback>* callbacks); | |
51 | |
52 private: | |
53 std::vector<ServiceWorkerClientInfo> clients_; | |
54 int request_id_; | |
55 std::map<int, int> pending_requests_; | |
56 }; | |
57 | |
26 namespace { | 58 namespace { |
27 | 59 |
28 // Default delay for scheduled stop. | 60 // Default delay for scheduled stop. |
29 // (Note that if all references to the version is dropped the worker | 61 // (Note that if all references to the version is dropped the worker |
30 // is also stopped without delay) | 62 // is also stopped without delay) |
31 const int64 kStopWorkerDelay = 30; // 30 secs. | 63 const int64 kStopWorkerDelay = 30; // 30 secs. |
32 | 64 |
33 // Default delay for scheduled update. | 65 // Default delay for scheduled update. |
34 const int kUpdateDelaySeconds = 1; | 66 const int kUpdateDelaySeconds = 1; |
35 | 67 |
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
570 SERVICE_WORKER_ERROR_FAILED, | 602 SERVICE_WORKER_ERROR_FAILED, |
571 SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK, | 603 SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK, |
572 ServiceWorkerResponse()); | 604 ServiceWorkerResponse()); |
573 RunIDMapCallbacks(&sync_callbacks_, | 605 RunIDMapCallbacks(&sync_callbacks_, |
574 SERVICE_WORKER_ERROR_FAILED); | 606 SERVICE_WORKER_ERROR_FAILED); |
575 RunIDMapCallbacks(&push_callbacks_, | 607 RunIDMapCallbacks(&push_callbacks_, |
576 SERVICE_WORKER_ERROR_FAILED); | 608 SERVICE_WORKER_ERROR_FAILED); |
577 RunIDMapCallbacks(&geofencing_callbacks_, | 609 RunIDMapCallbacks(&geofencing_callbacks_, |
578 SERVICE_WORKER_ERROR_FAILED); | 610 SERVICE_WORKER_ERROR_FAILED); |
579 | 611 |
612 GetClientInfoCallback::ClearCallbacks(&get_client_info_callbacks_); | |
613 | |
580 FOR_EACH_OBSERVER(Listener, listeners_, OnWorkerStopped(this)); | 614 FOR_EACH_OBSERVER(Listener, listeners_, OnWorkerStopped(this)); |
581 | 615 |
582 // There should be no more communication from/to a stopped worker. Deleting | 616 // There should be no more communication from/to a stopped worker. Deleting |
583 // the listener prevents any pending completion callbacks from causing | 617 // the listener prevents any pending completion callbacks from causing |
584 // messages to be sent to the stopped worker. | 618 // messages to be sent to the stopped worker. |
585 cache_listener_.reset(); | 619 cache_listener_.reset(); |
586 | 620 |
587 // Restart worker if we have any start callbacks and the worker isn't doomed. | 621 // Restart worker if we have any start callbacks and the worker isn't doomed. |
588 if (should_restart) { | 622 if (should_restart) { |
589 cache_listener_.reset(new ServiceWorkerCacheListener(this, context_)); | 623 cache_listener_.reset(new ServiceWorkerCacheListener(this, context_)); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
637 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_NotificationClickEventFinished, | 671 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_NotificationClickEventFinished, |
638 OnNotificationClickEventFinished) | 672 OnNotificationClickEventFinished) |
639 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PushEventFinished, | 673 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PushEventFinished, |
640 OnPushEventFinished) | 674 OnPushEventFinished) |
641 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GeofencingEventFinished, | 675 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GeofencingEventFinished, |
642 OnGeofencingEventFinished) | 676 OnGeofencingEventFinished) |
643 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessageToDocument, | 677 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessageToDocument, |
644 OnPostMessageToDocument) | 678 OnPostMessageToDocument) |
645 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_FocusClient, | 679 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_FocusClient, |
646 OnFocusClient) | 680 OnFocusClient) |
681 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GetClientInfoSuccess, | |
682 OnGetClientInfoSuccess) | |
683 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GetClientInfoError, | |
684 OnGetClientInfoError) | |
647 IPC_MESSAGE_UNHANDLED(handled = false) | 685 IPC_MESSAGE_UNHANDLED(handled = false) |
648 IPC_END_MESSAGE_MAP() | 686 IPC_END_MESSAGE_MAP() |
649 return handled; | 687 return handled; |
650 } | 688 } |
651 | 689 |
652 void ServiceWorkerVersion::OnStartMessageSent( | 690 void ServiceWorkerVersion::OnStartMessageSent( |
653 ServiceWorkerStatusCode status) { | 691 ServiceWorkerStatusCode status) { |
654 if (status != SERVICE_WORKER_OK) | 692 if (status != SERVICE_WORKER_OK) |
655 RunCallbacks(this, &start_callbacks_, status); | 693 RunCallbacks(this, &start_callbacks_, status); |
656 } | 694 } |
(...skipping 21 matching lines...) Expand all Loading... | |
678 int request_id = activate_callbacks_.Add(new StatusCallback(callback)); | 716 int request_id = activate_callbacks_.Add(new StatusCallback(callback)); |
679 ServiceWorkerStatusCode status = | 717 ServiceWorkerStatusCode status = |
680 embedded_worker_->SendMessage(ServiceWorkerMsg_ActivateEvent(request_id)); | 718 embedded_worker_->SendMessage(ServiceWorkerMsg_ActivateEvent(request_id)); |
681 if (status != SERVICE_WORKER_OK) { | 719 if (status != SERVICE_WORKER_OK) { |
682 activate_callbacks_.Remove(request_id); | 720 activate_callbacks_.Remove(request_id); |
683 RunSoon(base::Bind(callback, status)); | 721 RunSoon(base::Bind(callback, status)); |
684 } | 722 } |
685 } | 723 } |
686 | 724 |
687 void ServiceWorkerVersion::OnGetClientDocuments(int request_id) { | 725 void ServiceWorkerVersion::OnGetClientDocuments(int request_id) { |
688 std::vector<int> client_ids; | 726 if (controllee_by_id_.IsEmpty()) { |
727 if (running_status() == RUNNING) { | |
728 embedded_worker_->SendMessage( | |
729 ServiceWorkerMsg_DidGetClientDocuments(request_id, | |
730 std::vector<ServiceWorkerClientInfo>())); | |
731 } | |
732 return; | |
733 } | |
734 GetClientInfoCallback* callback = new GetClientInfoCallback(request_id); | |
689 ControlleeByIDMap::iterator it(&controllee_by_id_); | 735 ControlleeByIDMap::iterator it(&controllee_by_id_); |
690 TRACE_EVENT0("ServiceWorker", | 736 TRACE_EVENT0("ServiceWorker", |
691 "ServiceWorkerVersion::OnGetClientDocuments"); | 737 "ServiceWorkerVersion::OnGetClientDocuments"); |
692 while (!it.IsAtEnd()) { | 738 while (!it.IsAtEnd()) { |
693 client_ids.push_back(it.GetCurrentKey()); | 739 int client_request_id = get_client_info_callbacks_.Add(callback); |
740 callback->add(client_request_id, it.GetCurrentKey()); | |
741 it.GetCurrentValue()->GetClientInfo(embedded_worker_->embedded_worker_id(), | |
742 client_request_id); | |
694 it.Advance(); | 743 it.Advance(); |
695 } | 744 } |
745 } | |
746 | |
747 void ServiceWorkerVersion::OnGetClientInfoSuccess( | |
748 int request_id, | |
749 const ServiceWorkerClientInfo& info) { | |
750 GetClientInfoCallback* callback = | |
751 get_client_info_callbacks_.Lookup(request_id); | |
752 if (!callback) { | |
753 NOTREACHED() << "Got unexpected message: " << request_id; | |
754 return; | |
755 } | |
756 get_client_info_callbacks_.Remove(request_id); | |
757 | |
758 callback->success(request_id, info); | |
759 if (callback->has_pending_requests()) | |
760 return; | |
761 | |
696 // Don't bother if it's no longer running. | 762 // Don't bother if it's no longer running. |
697 if (running_status() == RUNNING) { | 763 if (running_status() == RUNNING) { |
698 embedded_worker_->SendMessage( | 764 embedded_worker_->SendMessage( |
699 ServiceWorkerMsg_DidGetClientDocuments(request_id, client_ids)); | 765 ServiceWorkerMsg_DidGetClientDocuments(callback->request_id(), |
766 callback->clients())); | |
700 } | 767 } |
768 delete callback; | |
769 } | |
770 | |
771 void ServiceWorkerVersion::OnGetClientInfoError(int request_id) { | |
772 GetClientInfoCallback* callback = | |
773 get_client_info_callbacks_.Lookup(request_id); | |
774 if (!callback) { | |
775 NOTREACHED() << "Got unexpected message: " << request_id; | |
776 return; | |
777 } | |
778 get_client_info_callbacks_.Remove(request_id); | |
779 | |
780 callback->error(request_id); | |
781 if (callback->has_pending_requests()) | |
782 return; | |
783 | |
784 // Don't bother if it's no longer running. | |
785 if (running_status() == RUNNING) { | |
786 embedded_worker_->SendMessage( | |
787 ServiceWorkerMsg_DidGetClientDocuments(callback->request_id(), | |
788 callback->clients())); | |
789 } | |
790 delete callback; | |
701 } | 791 } |
702 | 792 |
703 void ServiceWorkerVersion::OnActivateEventFinished( | 793 void ServiceWorkerVersion::OnActivateEventFinished( |
704 int request_id, | 794 int request_id, |
705 blink::WebServiceWorkerEventResult result) { | 795 blink::WebServiceWorkerEventResult result) { |
706 DCHECK(ACTIVATING == status() || | 796 DCHECK(ACTIVATING == status() || |
707 REDUNDANT == status()) << status(); | 797 REDUNDANT == status()) << status(); |
708 TRACE_EVENT0("ServiceWorker", | 798 TRACE_EVENT0("ServiceWorker", |
709 "ServiceWorkerVersion::OnActivateEventFinished"); | 799 "ServiceWorkerVersion::OnActivateEventFinished"); |
710 | 800 |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
893 DCHECK(!HasControllee()); | 983 DCHECK(!HasControllee()); |
894 SetStatus(REDUNDANT); | 984 SetStatus(REDUNDANT); |
895 StopWorker(base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); | 985 StopWorker(base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); |
896 if (!context_) | 986 if (!context_) |
897 return; | 987 return; |
898 std::vector<ServiceWorkerDatabase::ResourceRecord> resources; | 988 std::vector<ServiceWorkerDatabase::ResourceRecord> resources; |
899 script_cache_map_.GetResources(&resources); | 989 script_cache_map_.GetResources(&resources); |
900 context_->storage()->PurgeResources(resources); | 990 context_->storage()->PurgeResources(resources); |
901 } | 991 } |
902 | 992 |
993 void ServiceWorkerVersion::GetClientInfoCallback::ClearCallbacks( | |
994 IDMap<GetClientInfoCallback>* callbacks) { | |
995 IDMap<GetClientInfoCallback>::iterator iter(callbacks); | |
996 while (!iter.IsAtEnd()) { | |
997 GetClientInfoCallback* callback = iter.GetCurrentValue(); | |
998 callback->cancel(iter.GetCurrentKey()); | |
999 if (!callback->has_pending_requests()) | |
nhiroki
2014/12/08 05:45:08
This condition seems never fulfilled because only
nhiroki
2014/12/08 05:47:05
CORRECTION: |has_pending_requests()| is **true**
Kunihiko Sakamoto
2014/12/08 06:43:18
callback->Cancel() above decrements pending_reques
nhiroki
2014/12/08 07:09:33
Ah sorry, I missed the cancel above. That makes se
| |
1000 delete callback; | |
1001 iter.Advance(); | |
1002 } | |
1003 callbacks->Clear(); | |
nhiroki
2014/12/08 05:45:08
After clearing |callbacks|, GetClientInfo{Success,
Kunihiko Sakamoto
2014/12/08 06:43:18
I see. Removed NOTREACHEDs.
I wonder if other call
nhiroki
2014/12/08 07:09:33
I think other event completion messages (eg. Activ
| |
1004 } | |
1005 | |
903 } // namespace content | 1006 } // namespace content |
OLD | NEW |