Chromium Code Reviews| 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/memory/ref_counted.h" |
| 9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
| 10 #include "base/strings/string16.h" | 10 #include "base/strings/string16.h" |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 36 | 36 |
| 37 void AddClientInfo(int client_id, const ServiceWorkerClientInfo& info) { | 37 void AddClientInfo(int client_id, const ServiceWorkerClientInfo& info) { |
| 38 clients_.push_back(info); | 38 clients_.push_back(info); |
| 39 clients_.back().client_id = client_id; | 39 clients_.back().client_id = client_id; |
| 40 } | 40 } |
| 41 | 41 |
| 42 private: | 42 private: |
| 43 friend class base::RefCounted<GetClientDocumentsCallback>; | 43 friend class base::RefCounted<GetClientDocumentsCallback>; |
| 44 | 44 |
| 45 virtual ~GetClientDocumentsCallback() { | 45 virtual ~GetClientDocumentsCallback() { |
| 46 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 47 | |
| 46 if (version_->running_status() == RUNNING) { | 48 if (version_->running_status() == RUNNING) { |
| 47 version_->embedded_worker_->SendMessage( | 49 version_->embedded_worker_->SendMessage( |
| 48 ServiceWorkerMsg_DidGetClientDocuments(request_id_, clients_)); | 50 ServiceWorkerMsg_DidGetClientDocuments(request_id_, clients_)); |
| 49 } | 51 } |
| 50 } | 52 } |
| 51 | 53 |
| 52 std::vector<ServiceWorkerClientInfo> clients_; | 54 std::vector<ServiceWorkerClientInfo> clients_; |
| 53 int request_id_; | 55 int request_id_; |
| 54 | 56 |
| 55 // |version_| must outlive this callback. | 57 // |version_| must outlive this callback. |
|
michaeln
2015/01/27 23:12:56
comment not really needed anymore
mlamouri (slow - plz ping)
2015/01/28 11:35:05
Removed.
| |
| 56 ServiceWorkerVersion* version_; | 58 scoped_refptr<ServiceWorkerVersion> version_; |
| 57 | 59 |
| 58 DISALLOW_COPY_AND_ASSIGN(GetClientDocumentsCallback); | 60 DISALLOW_COPY_AND_ASSIGN(GetClientDocumentsCallback); |
| 59 }; | 61 }; |
| 60 | 62 |
| 61 namespace { | 63 namespace { |
| 62 | 64 |
| 63 // Default delay for scheduled stop. | 65 // Default delay for scheduled stop. |
| 64 // (Note that if all references to the version is dropped the worker | 66 // (Note that if all references to the version is dropped the worker |
| 65 // is also stopped without delay) | 67 // is also stopped without delay) |
| 66 const int64 kStopWorkerDelay = 30; // 30 secs. | 68 const int64 kStopWorkerDelay = 30; // 30 secs. |
| (...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 599 &new_routing_ids); | 601 &new_routing_ids); |
| 600 ServiceWorkerStatusCode status = | 602 ServiceWorkerStatusCode status = |
| 601 embedded_worker_->SendMessage(ServiceWorkerMsg_CrossOriginMessageToWorker( | 603 embedded_worker_->SendMessage(ServiceWorkerMsg_CrossOriginMessageToWorker( |
| 602 client, message, sent_message_port_ids, new_routing_ids)); | 604 client, message, sent_message_port_ids, new_routing_ids)); |
| 603 RunSoon(base::Bind(callback, status)); | 605 RunSoon(base::Bind(callback, status)); |
| 604 } | 606 } |
| 605 void ServiceWorkerVersion::AddControllee( | 607 void ServiceWorkerVersion::AddControllee( |
| 606 ServiceWorkerProviderHost* provider_host) { | 608 ServiceWorkerProviderHost* provider_host) { |
| 607 DCHECK(!ContainsKey(controllee_map_, provider_host)); | 609 DCHECK(!ContainsKey(controllee_map_, provider_host)); |
| 608 int controllee_id = controllee_by_id_.Add(provider_host); | 610 int controllee_id = controllee_by_id_.Add(provider_host); |
| 611 // IDMap<>'s last index is kInvalidServiceWorkerClientId. | |
| 612 CHECK(controllee_id != kInvalidServiceWorkerClientId); | |
| 609 controllee_map_[provider_host] = controllee_id; | 613 controllee_map_[provider_host] = controllee_id; |
| 610 // Reset the timer if it's running (so that it's kept alive a bit longer | 614 // Reset the timer if it's running (so that it's kept alive a bit longer |
| 611 // right after a new controllee is added). | 615 // right after a new controllee is added). |
| 612 ScheduleStopWorker(); | 616 ScheduleStopWorker(); |
| 613 } | 617 } |
| 614 | 618 |
| 615 void ServiceWorkerVersion::RemoveControllee( | 619 void ServiceWorkerVersion::RemoveControllee( |
| 616 ServiceWorkerProviderHost* provider_host) { | 620 ServiceWorkerProviderHost* provider_host) { |
| 617 ControlleeMap::iterator found = controllee_map_.find(provider_host); | 621 ControlleeMap::iterator found = controllee_map_.find(provider_host); |
| 618 DCHECK(found != controllee_map_.end()); | 622 DCHECK(found != controllee_map_.end()); |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 709 SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK, | 713 SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK, |
| 710 ServiceWorkerResponse()); | 714 ServiceWorkerResponse()); |
| 711 RunIDMapCallbacks(&sync_callbacks_, | 715 RunIDMapCallbacks(&sync_callbacks_, |
| 712 SERVICE_WORKER_ERROR_FAILED); | 716 SERVICE_WORKER_ERROR_FAILED); |
| 713 RunIDMapCallbacks(¬ification_click_callbacks_, | 717 RunIDMapCallbacks(¬ification_click_callbacks_, |
| 714 SERVICE_WORKER_ERROR_FAILED); | 718 SERVICE_WORKER_ERROR_FAILED); |
| 715 RunIDMapCallbacks(&push_callbacks_, | 719 RunIDMapCallbacks(&push_callbacks_, |
| 716 SERVICE_WORKER_ERROR_FAILED); | 720 SERVICE_WORKER_ERROR_FAILED); |
| 717 RunIDMapCallbacks(&geofencing_callbacks_, | 721 RunIDMapCallbacks(&geofencing_callbacks_, |
| 718 SERVICE_WORKER_ERROR_FAILED); | 722 SERVICE_WORKER_ERROR_FAILED); |
| 719 RunIDMapCallbacks(&get_client_info_callbacks_, | |
| 720 SERVICE_WORKER_ERROR_FAILED, | |
| 721 ServiceWorkerClientInfo()); | |
| 722 RunIDMapCallbacks(&cross_origin_connect_callbacks_, | 723 RunIDMapCallbacks(&cross_origin_connect_callbacks_, |
| 723 SERVICE_WORKER_ERROR_FAILED, | 724 SERVICE_WORKER_ERROR_FAILED, |
| 724 false); | 725 false); |
| 725 | 726 |
| 726 streaming_url_request_jobs_.clear(); | 727 streaming_url_request_jobs_.clear(); |
| 727 | 728 |
| 728 FOR_EACH_OBSERVER(Listener, listeners_, OnWorkerStopped(this)); | 729 FOR_EACH_OBSERVER(Listener, listeners_, OnWorkerStopped(this)); |
| 729 | 730 |
| 730 // There should be no more communication from/to a stopped worker. Deleting | 731 // There should be no more communication from/to a stopped worker. Deleting |
| 731 // the listener prevents any pending completion callbacks from causing | 732 // the listener prevents any pending completion callbacks from causing |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 787 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PushEventFinished, | 788 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PushEventFinished, |
| 788 OnPushEventFinished) | 789 OnPushEventFinished) |
| 789 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GeofencingEventFinished, | 790 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GeofencingEventFinished, |
| 790 OnGeofencingEventFinished) | 791 OnGeofencingEventFinished) |
| 791 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_CrossOriginConnectEventFinished, | 792 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_CrossOriginConnectEventFinished, |
| 792 OnCrossOriginConnectEventFinished) | 793 OnCrossOriginConnectEventFinished) |
| 793 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessageToDocument, | 794 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessageToDocument, |
| 794 OnPostMessageToDocument) | 795 OnPostMessageToDocument) |
| 795 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_FocusClient, | 796 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_FocusClient, |
| 796 OnFocusClient) | 797 OnFocusClient) |
| 797 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GetClientInfoSuccess, | |
| 798 OnGetClientInfoSuccess) | |
| 799 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GetClientInfoError, | |
| 800 OnGetClientInfoError) | |
| 801 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SkipWaiting, | 798 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SkipWaiting, |
| 802 OnSkipWaiting) | 799 OnSkipWaiting) |
| 803 IPC_MESSAGE_UNHANDLED(handled = false) | 800 IPC_MESSAGE_UNHANDLED(handled = false) |
| 804 IPC_END_MESSAGE_MAP() | 801 IPC_END_MESSAGE_MAP() |
| 805 return handled; | 802 return handled; |
| 806 } | 803 } |
| 807 | 804 |
| 808 void ServiceWorkerVersion::OnStartMessageSent( | 805 void ServiceWorkerVersion::OnStartMessageSent( |
| 809 ServiceWorkerStatusCode status) { | 806 ServiceWorkerStatusCode status) { |
| 810 if (status != SERVICE_WORKER_OK) | 807 if (status != SERVICE_WORKER_OK) |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 848 std::vector<ServiceWorkerClientInfo>())); | 845 std::vector<ServiceWorkerClientInfo>())); |
| 849 } | 846 } |
| 850 return; | 847 return; |
| 851 } | 848 } |
| 852 scoped_refptr<GetClientDocumentsCallback> callback( | 849 scoped_refptr<GetClientDocumentsCallback> callback( |
| 853 new GetClientDocumentsCallback(request_id, this)); | 850 new GetClientDocumentsCallback(request_id, this)); |
| 854 ControlleeByIDMap::iterator it(&controllee_by_id_); | 851 ControlleeByIDMap::iterator it(&controllee_by_id_); |
| 855 TRACE_EVENT0("ServiceWorker", | 852 TRACE_EVENT0("ServiceWorker", |
| 856 "ServiceWorkerVersion::OnGetClientDocuments"); | 853 "ServiceWorkerVersion::OnGetClientDocuments"); |
| 857 while (!it.IsAtEnd()) { | 854 while (!it.IsAtEnd()) { |
| 858 int client_request_id = get_client_info_callbacks_.Add( | 855 it.GetCurrentValue()->GetClientInfo( |
| 859 new GetClientInfoCallback(base::Bind( | 856 base::Bind(&ServiceWorkerVersion::DidGetClientInfo, |
| 860 &ServiceWorkerVersion::DidGetClientInfo, | 857 weak_factory_.GetWeakPtr(), it.GetCurrentKey(), callback)); |
|
michaeln
2015/01/27 23:12:56
Just attended the code prple speed meeting and aft
mlamouri (slow - plz ping)
2015/01/28 11:35:05
That sounds good. I would be happy to do that but
michaeln
2015/01/28 20:26:21
sgtm, TODO?
| |
| 861 weak_factory_.GetWeakPtr(), it.GetCurrentKey(), callback))); | |
| 862 it.GetCurrentValue()->GetClientInfo(embedded_worker_->embedded_worker_id(), | |
| 863 client_request_id); | |
| 864 it.Advance(); | 858 it.Advance(); |
| 865 } | 859 } |
| 866 } | 860 } |
| 867 | 861 |
| 868 void ServiceWorkerVersion::OnGetClientInfoSuccess( | |
| 869 int request_id, | |
| 870 const ServiceWorkerClientInfo& info) { | |
| 871 GetClientInfoCallback* callback = | |
| 872 get_client_info_callbacks_.Lookup(request_id); | |
| 873 if (!callback) { | |
| 874 // The callback may already have been cleared by OnStopped, just ignore. | |
| 875 return; | |
| 876 } | |
| 877 callback->Run(SERVICE_WORKER_OK, info); | |
| 878 RemoveCallbackAndStopIfDoomed(&get_client_info_callbacks_, request_id); | |
| 879 } | |
| 880 | |
| 881 void ServiceWorkerVersion::OnGetClientInfoError(int request_id) { | |
| 882 GetClientInfoCallback* callback = | |
| 883 get_client_info_callbacks_.Lookup(request_id); | |
| 884 if (!callback) { | |
| 885 // The callback may already have been cleared by OnStopped, just ignore. | |
| 886 return; | |
| 887 } | |
| 888 callback->Run(SERVICE_WORKER_ERROR_FAILED, ServiceWorkerClientInfo()); | |
| 889 RemoveCallbackAndStopIfDoomed(&get_client_info_callbacks_, request_id); | |
| 890 } | |
| 891 | |
| 892 void ServiceWorkerVersion::OnActivateEventFinished( | 862 void ServiceWorkerVersion::OnActivateEventFinished( |
| 893 int request_id, | 863 int request_id, |
| 894 blink::WebServiceWorkerEventResult result) { | 864 blink::WebServiceWorkerEventResult result) { |
| 895 DCHECK(ACTIVATING == status() || | 865 DCHECK(ACTIVATING == status() || |
| 896 REDUNDANT == status()) << status(); | 866 REDUNDANT == status()) << status(); |
| 897 TRACE_EVENT0("ServiceWorker", | 867 TRACE_EVENT0("ServiceWorker", |
| 898 "ServiceWorkerVersion::OnActivateEventFinished"); | 868 "ServiceWorkerVersion::OnActivateEventFinished"); |
| 899 | 869 |
| 900 StatusCallback* callback = activate_callbacks_.Lookup(request_id); | 870 StatusCallback* callback = activate_callbacks_.Lookup(request_id); |
| 901 if (!callback) { | 871 if (!callback) { |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1101 } | 1071 } |
| 1102 | 1072 |
| 1103 void ServiceWorkerVersion::DidSkipWaiting(int request_id) { | 1073 void ServiceWorkerVersion::DidSkipWaiting(int request_id) { |
| 1104 if (running_status() == STARTING || running_status() == RUNNING) | 1074 if (running_status() == STARTING || running_status() == RUNNING) |
| 1105 embedded_worker_->SendMessage(ServiceWorkerMsg_DidSkipWaiting(request_id)); | 1075 embedded_worker_->SendMessage(ServiceWorkerMsg_DidSkipWaiting(request_id)); |
| 1106 } | 1076 } |
| 1107 | 1077 |
| 1108 void ServiceWorkerVersion::DidGetClientInfo( | 1078 void ServiceWorkerVersion::DidGetClientInfo( |
| 1109 int client_id, | 1079 int client_id, |
| 1110 scoped_refptr<GetClientDocumentsCallback> callback, | 1080 scoped_refptr<GetClientDocumentsCallback> callback, |
| 1111 ServiceWorkerStatusCode status, | |
| 1112 const ServiceWorkerClientInfo& info) { | 1081 const ServiceWorkerClientInfo& info) { |
| 1113 if (status == SERVICE_WORKER_OK) | 1082 // If the request to the provider_host returned an empty |
| 1114 callback->AddClientInfo(client_id, info); | 1083 // ServiceWorkerClientInfo, that means that it wasn't possible to associated |
| 1084 // it with a valid RenderFrameHost. It might be because the frame was killed | |
| 1085 // or navigated in between. | |
| 1086 if (info.IsEmpty()) | |
| 1087 return; | |
| 1088 callback->AddClientInfo(client_id, info); | |
| 1115 } | 1089 } |
| 1116 | 1090 |
| 1117 void ServiceWorkerVersion::ScheduleStopWorker() { | 1091 void ServiceWorkerVersion::ScheduleStopWorker() { |
| 1118 if (running_status() != RUNNING) | 1092 if (running_status() != RUNNING) |
| 1119 return; | 1093 return; |
| 1120 stop_worker_timer_.Stop(); | 1094 stop_worker_timer_.Stop(); |
| 1121 stop_worker_timer_.Start( | 1095 stop_worker_timer_.Start( |
| 1122 FROM_HERE, base::TimeDelta::FromSeconds( | 1096 FROM_HERE, base::TimeDelta::FromSeconds( |
| 1123 is_doomed_ ? kStopDoomedWorkerDelay : kStopWorkerDelay), | 1097 is_doomed_ ? kStopDoomedWorkerDelay : kStopWorkerDelay), |
| 1124 base::Bind(&ServiceWorkerVersion::StopWorkerIfIdle, | 1098 base::Bind(&ServiceWorkerVersion::StopWorkerIfIdle, |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 1142 | 1116 |
| 1143 bool ServiceWorkerVersion::HasInflightRequests() const { | 1117 bool ServiceWorkerVersion::HasInflightRequests() const { |
| 1144 return | 1118 return |
| 1145 !activate_callbacks_.IsEmpty() || | 1119 !activate_callbacks_.IsEmpty() || |
| 1146 !install_callbacks_.IsEmpty() || | 1120 !install_callbacks_.IsEmpty() || |
| 1147 !fetch_callbacks_.IsEmpty() || | 1121 !fetch_callbacks_.IsEmpty() || |
| 1148 !sync_callbacks_.IsEmpty() || | 1122 !sync_callbacks_.IsEmpty() || |
| 1149 !notification_click_callbacks_.IsEmpty() || | 1123 !notification_click_callbacks_.IsEmpty() || |
| 1150 !push_callbacks_.IsEmpty() || | 1124 !push_callbacks_.IsEmpty() || |
| 1151 !geofencing_callbacks_.IsEmpty() || | 1125 !geofencing_callbacks_.IsEmpty() || |
| 1152 !get_client_info_callbacks_.IsEmpty() || | |
| 1153 !cross_origin_connect_callbacks_.IsEmpty() || | 1126 !cross_origin_connect_callbacks_.IsEmpty() || |
| 1154 !streaming_url_request_jobs_.empty(); | 1127 !streaming_url_request_jobs_.empty(); |
| 1155 } | 1128 } |
| 1156 | 1129 |
| 1157 void ServiceWorkerVersion::DoomInternal() { | 1130 void ServiceWorkerVersion::DoomInternal() { |
| 1158 DCHECK(is_doomed_); | 1131 DCHECK(is_doomed_); |
| 1159 DCHECK(!HasControllee()); | 1132 DCHECK(!HasControllee()); |
| 1160 SetStatus(REDUNDANT); | 1133 SetStatus(REDUNDANT); |
| 1161 StopWorkerIfIdle(); | 1134 StopWorkerIfIdle(); |
| 1162 if (!context_) | 1135 if (!context_) |
| 1163 return; | 1136 return; |
| 1164 std::vector<ServiceWorkerDatabase::ResourceRecord> resources; | 1137 std::vector<ServiceWorkerDatabase::ResourceRecord> resources; |
| 1165 script_cache_map_.GetResources(&resources); | 1138 script_cache_map_.GetResources(&resources); |
| 1166 context_->storage()->PurgeResources(resources); | 1139 context_->storage()->PurgeResources(resources); |
| 1167 } | 1140 } |
| 1168 | 1141 |
| 1169 template <typename IDMAP> | 1142 template <typename IDMAP> |
| 1170 void ServiceWorkerVersion::RemoveCallbackAndStopIfDoomed( | 1143 void ServiceWorkerVersion::RemoveCallbackAndStopIfDoomed( |
| 1171 IDMAP* callbacks, | 1144 IDMAP* callbacks, |
| 1172 int request_id) { | 1145 int request_id) { |
| 1173 callbacks->Remove(request_id); | 1146 callbacks->Remove(request_id); |
| 1174 if (is_doomed_) { | 1147 if (is_doomed_) { |
| 1175 // The stop should be already scheduled, but try to stop immediately, in | 1148 // The stop should be already scheduled, but try to stop immediately, in |
| 1176 // order to release worker resources soon. | 1149 // order to release worker resources soon. |
| 1177 StopWorkerIfIdle(); | 1150 StopWorkerIfIdle(); |
| 1178 } | 1151 } |
| 1179 } | 1152 } |
| 1180 | 1153 |
| 1181 } // namespace content | 1154 } // namespace content |
| OLD | NEW |