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/memory/ref_counted.h" |
8 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
9 #include "base/strings/string16.h" | 10 #include "base/strings/string16.h" |
10 #include "content/browser/message_port_message_filter.h" | 11 #include "content/browser/message_port_message_filter.h" |
11 #include "content/browser/message_port_service.h" | 12 #include "content/browser/message_port_service.h" |
12 #include "content/browser/service_worker/embedded_worker_instance.h" | 13 #include "content/browser/service_worker/embedded_worker_instance.h" |
13 #include "content/browser/service_worker/embedded_worker_registry.h" | 14 #include "content/browser/service_worker/embedded_worker_registry.h" |
14 #include "content/browser/service_worker/service_worker_context_core.h" | 15 #include "content/browser/service_worker/service_worker_context_core.h" |
15 #include "content/browser/service_worker/service_worker_registration.h" | 16 #include "content/browser/service_worker/service_worker_registration.h" |
16 #include "content/browser/service_worker/service_worker_utils.h" | 17 #include "content/browser/service_worker/service_worker_utils.h" |
17 #include "content/common/service_worker/service_worker_messages.h" | 18 #include "content/common/service_worker/service_worker_messages.h" |
18 #include "content/public/browser/browser_thread.h" | 19 #include "content/public/browser/browser_thread.h" |
19 #include "content/public/common/content_switches.h" | 20 #include "content/public/common/content_switches.h" |
20 | 21 |
21 namespace content { | 22 namespace content { |
22 | 23 |
23 typedef ServiceWorkerVersion::StatusCallback StatusCallback; | 24 typedef ServiceWorkerVersion::StatusCallback StatusCallback; |
24 typedef ServiceWorkerVersion::MessageCallback MessageCallback; | 25 typedef ServiceWorkerVersion::MessageCallback MessageCallback; |
25 | 26 |
| 27 class ServiceWorkerVersion::GetClientDocumentsCallback |
| 28 : public base::RefCounted<GetClientDocumentsCallback> { |
| 29 public: |
| 30 GetClientDocumentsCallback(int request_id, int pending_requests) |
| 31 : request_id_(request_id), |
| 32 pending_requests_(pending_requests) {} |
| 33 void AddClientInfo(int client_id, const ServiceWorkerClientInfo& info) { |
| 34 clients_.push_back(info); |
| 35 clients_.back().client_id = client_id; |
| 36 } |
| 37 void DecrementPendingRequests(ServiceWorkerVersion* version) { |
| 38 if (--pending_requests_ > 0) |
| 39 return; |
| 40 // Don't bother if it's no longer running. |
| 41 if (version->running_status() == RUNNING) { |
| 42 version->embedded_worker_->SendMessage( |
| 43 ServiceWorkerMsg_DidGetClientDocuments(request_id_, clients_)); |
| 44 } |
| 45 } |
| 46 |
| 47 private: |
| 48 friend class base::RefCounted<GetClientDocumentsCallback>; |
| 49 virtual ~GetClientDocumentsCallback() {} |
| 50 |
| 51 std::vector<ServiceWorkerClientInfo> clients_; |
| 52 int request_id_; |
| 53 size_t pending_requests_; |
| 54 |
| 55 DISALLOW_COPY_AND_ASSIGN(GetClientDocumentsCallback); |
| 56 }; |
| 57 |
| 58 class ServiceWorkerVersion::GetClientInfoCallback { |
| 59 public: |
| 60 GetClientInfoCallback( |
| 61 int client_id, |
| 62 const scoped_refptr<GetClientDocumentsCallback>& callback) |
| 63 : client_id_(client_id), |
| 64 callback_(callback) {} |
| 65 |
| 66 void OnSuccess(ServiceWorkerVersion* version, |
| 67 const ServiceWorkerClientInfo& info) { |
| 68 callback_->AddClientInfo(client_id_, info); |
| 69 callback_->DecrementPendingRequests(version); |
| 70 } |
| 71 void OnError(ServiceWorkerVersion* version) { |
| 72 callback_->DecrementPendingRequests(version); |
| 73 } |
| 74 |
| 75 private: |
| 76 int client_id_; |
| 77 scoped_refptr<GetClientDocumentsCallback> callback_; |
| 78 |
| 79 DISALLOW_COPY_AND_ASSIGN(GetClientInfoCallback); |
| 80 }; |
| 81 |
26 namespace { | 82 namespace { |
27 | 83 |
28 // Default delay for scheduled stop. | 84 // Default delay for scheduled stop. |
29 // (Note that if all references to the version is dropped the worker | 85 // (Note that if all references to the version is dropped the worker |
30 // is also stopped without delay) | 86 // is also stopped without delay) |
31 const int64 kStopWorkerDelay = 30; // 30 secs. | 87 const int64 kStopWorkerDelay = 30; // 30 secs. |
32 | 88 |
33 // Default delay for scheduled update. | 89 // Default delay for scheduled update. |
34 const int kUpdateDelaySeconds = 1; | 90 const int kUpdateDelaySeconds = 1; |
35 | 91 |
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
574 SERVICE_WORKER_ERROR_FAILED, | 630 SERVICE_WORKER_ERROR_FAILED, |
575 SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK, | 631 SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK, |
576 ServiceWorkerResponse()); | 632 ServiceWorkerResponse()); |
577 RunIDMapCallbacks(&sync_callbacks_, | 633 RunIDMapCallbacks(&sync_callbacks_, |
578 SERVICE_WORKER_ERROR_FAILED); | 634 SERVICE_WORKER_ERROR_FAILED); |
579 RunIDMapCallbacks(&push_callbacks_, | 635 RunIDMapCallbacks(&push_callbacks_, |
580 SERVICE_WORKER_ERROR_FAILED); | 636 SERVICE_WORKER_ERROR_FAILED); |
581 RunIDMapCallbacks(&geofencing_callbacks_, | 637 RunIDMapCallbacks(&geofencing_callbacks_, |
582 SERVICE_WORKER_ERROR_FAILED); | 638 SERVICE_WORKER_ERROR_FAILED); |
583 | 639 |
| 640 get_client_info_callbacks_.Clear(); |
| 641 |
584 FOR_EACH_OBSERVER(Listener, listeners_, OnWorkerStopped(this)); | 642 FOR_EACH_OBSERVER(Listener, listeners_, OnWorkerStopped(this)); |
585 | 643 |
586 // There should be no more communication from/to a stopped worker. Deleting | 644 // There should be no more communication from/to a stopped worker. Deleting |
587 // the listener prevents any pending completion callbacks from causing | 645 // the listener prevents any pending completion callbacks from causing |
588 // messages to be sent to the stopped worker. | 646 // messages to be sent to the stopped worker. |
589 cache_listener_.reset(); | 647 cache_listener_.reset(); |
590 | 648 |
591 // Restart worker if we have any start callbacks and the worker isn't doomed. | 649 // Restart worker if we have any start callbacks and the worker isn't doomed. |
592 if (should_restart) { | 650 if (should_restart) { |
593 cache_listener_.reset(new ServiceWorkerCacheListener(this, context_)); | 651 cache_listener_.reset(new ServiceWorkerCacheListener(this, context_)); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
641 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_NotificationClickEventFinished, | 699 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_NotificationClickEventFinished, |
642 OnNotificationClickEventFinished) | 700 OnNotificationClickEventFinished) |
643 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PushEventFinished, | 701 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PushEventFinished, |
644 OnPushEventFinished) | 702 OnPushEventFinished) |
645 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GeofencingEventFinished, | 703 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GeofencingEventFinished, |
646 OnGeofencingEventFinished) | 704 OnGeofencingEventFinished) |
647 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessageToDocument, | 705 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessageToDocument, |
648 OnPostMessageToDocument) | 706 OnPostMessageToDocument) |
649 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_FocusClient, | 707 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_FocusClient, |
650 OnFocusClient) | 708 OnFocusClient) |
| 709 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GetClientInfoSuccess, |
| 710 OnGetClientInfoSuccess) |
| 711 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GetClientInfoError, |
| 712 OnGetClientInfoError) |
651 IPC_MESSAGE_UNHANDLED(handled = false) | 713 IPC_MESSAGE_UNHANDLED(handled = false) |
652 IPC_END_MESSAGE_MAP() | 714 IPC_END_MESSAGE_MAP() |
653 return handled; | 715 return handled; |
654 } | 716 } |
655 | 717 |
656 void ServiceWorkerVersion::OnStartMessageSent( | 718 void ServiceWorkerVersion::OnStartMessageSent( |
657 ServiceWorkerStatusCode status) { | 719 ServiceWorkerStatusCode status) { |
658 if (status != SERVICE_WORKER_OK) | 720 if (status != SERVICE_WORKER_OK) |
659 RunCallbacks(this, &start_callbacks_, status); | 721 RunCallbacks(this, &start_callbacks_, status); |
660 } | 722 } |
(...skipping 21 matching lines...) Expand all Loading... |
682 int request_id = activate_callbacks_.Add(new StatusCallback(callback)); | 744 int request_id = activate_callbacks_.Add(new StatusCallback(callback)); |
683 ServiceWorkerStatusCode status = | 745 ServiceWorkerStatusCode status = |
684 embedded_worker_->SendMessage(ServiceWorkerMsg_ActivateEvent(request_id)); | 746 embedded_worker_->SendMessage(ServiceWorkerMsg_ActivateEvent(request_id)); |
685 if (status != SERVICE_WORKER_OK) { | 747 if (status != SERVICE_WORKER_OK) { |
686 activate_callbacks_.Remove(request_id); | 748 activate_callbacks_.Remove(request_id); |
687 RunSoon(base::Bind(callback, status)); | 749 RunSoon(base::Bind(callback, status)); |
688 } | 750 } |
689 } | 751 } |
690 | 752 |
691 void ServiceWorkerVersion::OnGetClientDocuments(int request_id) { | 753 void ServiceWorkerVersion::OnGetClientDocuments(int request_id) { |
692 std::vector<int> client_ids; | 754 if (controllee_by_id_.IsEmpty()) { |
| 755 if (running_status() == RUNNING) { |
| 756 embedded_worker_->SendMessage( |
| 757 ServiceWorkerMsg_DidGetClientDocuments(request_id, |
| 758 std::vector<ServiceWorkerClientInfo>())); |
| 759 } |
| 760 return; |
| 761 } |
| 762 scoped_refptr<GetClientDocumentsCallback> callback( |
| 763 new GetClientDocumentsCallback(request_id, controllee_by_id_.size())); |
693 ControlleeByIDMap::iterator it(&controllee_by_id_); | 764 ControlleeByIDMap::iterator it(&controllee_by_id_); |
694 TRACE_EVENT0("ServiceWorker", | 765 TRACE_EVENT0("ServiceWorker", |
695 "ServiceWorkerVersion::OnGetClientDocuments"); | 766 "ServiceWorkerVersion::OnGetClientDocuments"); |
696 while (!it.IsAtEnd()) { | 767 while (!it.IsAtEnd()) { |
697 client_ids.push_back(it.GetCurrentKey()); | 768 int client_request_id = get_client_info_callbacks_.Add( |
| 769 new GetClientInfoCallback(it.GetCurrentKey(), callback)); |
| 770 it.GetCurrentValue()->GetClientInfo(embedded_worker_->embedded_worker_id(), |
| 771 client_request_id); |
698 it.Advance(); | 772 it.Advance(); |
699 } | 773 } |
700 // Don't bother if it's no longer running. | |
701 if (running_status() == RUNNING) { | |
702 embedded_worker_->SendMessage( | |
703 ServiceWorkerMsg_DidGetClientDocuments(request_id, client_ids)); | |
704 } | |
705 } | 774 } |
706 | 775 |
| 776 void ServiceWorkerVersion::OnGetClientInfoSuccess( |
| 777 int request_id, |
| 778 const ServiceWorkerClientInfo& info) { |
| 779 GetClientInfoCallback* callback = |
| 780 get_client_info_callbacks_.Lookup(request_id); |
| 781 if (!callback) { |
| 782 // The callback may already have been cleared by OnStopped, just ignore. |
| 783 return; |
| 784 } |
| 785 callback->OnSuccess(this, info); |
| 786 get_client_info_callbacks_.Remove(request_id); |
| 787 } |
| 788 |
| 789 void ServiceWorkerVersion::OnGetClientInfoError(int request_id) { |
| 790 GetClientInfoCallback* callback = |
| 791 get_client_info_callbacks_.Lookup(request_id); |
| 792 if (!callback) { |
| 793 // The callback may already have been cleared by OnStopped, just ignore. |
| 794 return; |
| 795 } |
| 796 callback->OnError(this); |
| 797 get_client_info_callbacks_.Remove(request_id); |
| 798 } |
| 799 |
707 void ServiceWorkerVersion::OnActivateEventFinished( | 800 void ServiceWorkerVersion::OnActivateEventFinished( |
708 int request_id, | 801 int request_id, |
709 blink::WebServiceWorkerEventResult result) { | 802 blink::WebServiceWorkerEventResult result) { |
710 DCHECK(ACTIVATING == status() || | 803 DCHECK(ACTIVATING == status() || |
711 REDUNDANT == status()) << status(); | 804 REDUNDANT == status()) << status(); |
712 TRACE_EVENT0("ServiceWorker", | 805 TRACE_EVENT0("ServiceWorker", |
713 "ServiceWorkerVersion::OnActivateEventFinished"); | 806 "ServiceWorkerVersion::OnActivateEventFinished"); |
714 | 807 |
715 StatusCallback* callback = activate_callbacks_.Lookup(request_id); | 808 StatusCallback* callback = activate_callbacks_.Lookup(request_id); |
716 if (!callback) { | 809 if (!callback) { |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
898 SetStatus(REDUNDANT); | 991 SetStatus(REDUNDANT); |
899 StopWorker(base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); | 992 StopWorker(base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); |
900 if (!context_) | 993 if (!context_) |
901 return; | 994 return; |
902 std::vector<ServiceWorkerDatabase::ResourceRecord> resources; | 995 std::vector<ServiceWorkerDatabase::ResourceRecord> resources; |
903 script_cache_map_.GetResources(&resources); | 996 script_cache_map_.GetResources(&resources); |
904 context_->storage()->PurgeResources(resources); | 997 context_->storage()->PurgeResources(resources); |
905 } | 998 } |
906 | 999 |
907 } // namespace content | 1000 } // namespace content |
OLD | NEW |