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/metrics/histogram_macros.h" | 9 #include "base/metrics/histogram_macros.h" |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
(...skipping 18 matching lines...) Expand all Loading... | |
29 #include "content/public/browser/content_browser_client.h" | 29 #include "content/public/browser/content_browser_client.h" |
30 #include "content/public/browser/page_navigator.h" | 30 #include "content/public/browser/page_navigator.h" |
31 #include "content/public/browser/render_frame_host.h" | 31 #include "content/public/browser/render_frame_host.h" |
32 #include "content/public/browser/render_process_host.h" | 32 #include "content/public/browser/render_process_host.h" |
33 #include "content/public/browser/web_contents.h" | 33 #include "content/public/browser/web_contents.h" |
34 #include "content/public/browser/web_contents_observer.h" | 34 #include "content/public/browser/web_contents_observer.h" |
35 #include "content/public/common/child_process_host.h" | 35 #include "content/public/common/child_process_host.h" |
36 #include "content/public/common/content_client.h" | 36 #include "content/public/common/content_client.h" |
37 #include "content/public/common/content_switches.h" | 37 #include "content/public/common/content_switches.h" |
38 #include "content/public/common/result_codes.h" | 38 #include "content/public/common/result_codes.h" |
39 #include "content/public/common/service_registry.h" | |
39 #include "net/http/http_response_headers.h" | 40 #include "net/http/http_response_headers.h" |
40 #include "net/http/http_response_info.h" | 41 #include "net/http/http_response_info.h" |
41 | 42 |
42 namespace content { | 43 namespace content { |
43 | 44 |
44 using StatusCallback = ServiceWorkerVersion::StatusCallback; | 45 using StatusCallback = ServiceWorkerVersion::StatusCallback; |
45 using ServiceWorkerClients = std::vector<ServiceWorkerClientInfo>; | 46 using ServiceWorkerClients = std::vector<ServiceWorkerClientInfo>; |
46 using GetClientsCallback = | 47 using GetClientsCallback = |
47 base::Callback<void(scoped_ptr<ServiceWorkerClients>)>; | 48 base::Callback<void(scoped_ptr<ServiceWorkerClients>)>; |
48 | 49 |
(...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
730 if (running_status() != RUNNING) { | 731 if (running_status() != RUNNING) { |
731 // Schedule calling this method after starting the worker. | 732 // Schedule calling this method after starting the worker. |
732 StartWorker(base::Bind(&RunTaskAfterStartWorker, | 733 StartWorker(base::Bind(&RunTaskAfterStartWorker, |
733 weak_factory_.GetWeakPtr(), callback, | 734 weak_factory_.GetWeakPtr(), callback, |
734 base::Bind(&self::DispatchSyncEvent, | 735 base::Bind(&self::DispatchSyncEvent, |
735 weak_factory_.GetWeakPtr(), | 736 weak_factory_.GetWeakPtr(), |
736 callback))); | 737 callback))); |
737 return; | 738 return; |
738 } | 739 } |
739 | 740 |
740 int request_id = AddRequest(callback, &sync_callbacks_, REQUEST_SYNC); | 741 // We can only get the embedded worker's process and thread ids on the IO |
741 ServiceWorkerStatusCode status = embedded_worker_->SendMessage( | 742 // thread, but we need to be on the UI thread to get the the mojo service |
742 ServiceWorkerMsg_SyncEvent(request_id)); | 743 // registry from the RenderProcessHost. |
743 if (status != SERVICE_WORKER_OK) { | 744 BrowserThread::PostTask( |
744 sync_callbacks_.Remove(request_id); | 745 BrowserThread::UI, FROM_HERE, |
745 RunSoon(base::Bind(callback, status)); | 746 base::Bind(&ServiceWorkerVersion::DispatchSyncEventOnUIThread, |
747 /* IS this the right one? */ base::Unretained(this), | |
jkarlin
2015/06/10 12:21:33
No, this is not safe. base::Unretained should rare
| |
748 embedded_worker_->process_id(), embedded_worker_->thread_id(), | |
749 callback)); | |
750 } | |
751 | |
752 void ServiceWorkerVersion::DispatchSyncEventOnUIThread( | |
753 int render_process_id, | |
754 int thread_id, | |
755 const StatusCallback& callback) { | |
756 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
757 // TODO(iclelland): Replace this with the real event registration details | |
758 content::SyncRegistrationPtr TEMP_null_event( | |
759 content::SyncRegistration::New()); | |
760 | |
761 RenderProcessHost* host = RenderProcessHost::FromID(render_process_id); | |
762 content::ServiceRegistry* registry = host->GetServiceRegistry(); | |
763 if (!registry) | |
764 return; | |
765 | |
766 if (!background_sync_client_.get()) | |
767 registry->ConnectToRemoteService(mojo::GetProxy(&background_sync_client_)); | |
768 background_sync_client_->Sync( | |
769 TEMP_null_event.Pass(), thread_id, | |
770 base::Bind(&ServiceWorkerVersion::OnSyncEventFinished, | |
771 weak_factory_.GetWeakPtr(), callback)); | |
772 } | |
773 | |
774 void ServiceWorkerVersion::OnSyncEventFinished( | |
775 const StatusCallback& callback, | |
776 BackgroundSyncEventStatus result) { | |
777 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
778 TRACE_EVENT0("ServiceWorker", "ServiceWorkerVersion::OnSyncEventFinished") | |
779 BrowserThread::PostTask( | |
780 BrowserThread::IO, FROM_HERE, | |
781 base::Bind(&ServiceWorkerVersion::FinishSyncEventOnIOThread, | |
782 /* IS this the right one? */ base::Unretained(this), callback, | |
783 result)); | |
784 } | |
785 | |
786 void ServiceWorkerVersion::FinishSyncEventOnIOThread( | |
787 const StatusCallback& callback, | |
788 BackgroundSyncEventStatus result) { | |
789 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
790 ServiceWorkerStatusCode status = SERVICE_WORKER_OK; | |
791 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( | |
792 switches::kEnableServiceWorkerSync)) { | |
793 // Avoid potential race condition where flag is disabled after a sync event | |
794 // was dispatched | |
795 status = SERVICE_WORKER_ERROR_ABORT; | |
796 } else if (result == BACKGROUND_SYNC_EVENT_STATUS_REJECTED) { | |
797 status = SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED; | |
798 } else if (result == BACKGROUND_SYNC_EVENT_STATUS_ABORT) { | |
799 status = SERVICE_WORKER_ERROR_ABORT; | |
800 } | |
801 | |
802 scoped_refptr<ServiceWorkerVersion> protect(this); | |
803 callback.Run(status); | |
804 | |
805 RestartTick(&idle_time_); | |
806 // TODO(iclelland) factor this out of RemoveCallbackAndStopIfRedundant | |
807 if (is_redundant()) { | |
808 // The stop should be already scheduled, but try to stop immediately, in | |
809 // order to release worker resources soon. | |
810 StopWorkerIfIdle(); | |
746 } | 811 } |
747 } | 812 } |
748 | 813 |
749 void ServiceWorkerVersion::DispatchNotificationClickEvent( | 814 void ServiceWorkerVersion::DispatchNotificationClickEvent( |
750 const StatusCallback& callback, | 815 const StatusCallback& callback, |
751 int64_t persistent_notification_id, | 816 int64_t persistent_notification_id, |
752 const PlatformNotificationData& notification_data) { | 817 const PlatformNotificationData& notification_data) { |
753 DCHECK_EQ(ACTIVATED, status()) << status(); | 818 DCHECK_EQ(ACTIVATED, status()) << status(); |
754 if (running_status() != RUNNING) { | 819 if (running_status() != RUNNING) { |
755 // Schedule calling this method after starting the worker. | 820 // Schedule calling this method after starting the worker. |
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1089 // callbacks for events). | 1154 // callbacks for events). |
1090 // TODO(kinuko): Consider if we want to add queue+resend mechanism here. | 1155 // TODO(kinuko): Consider if we want to add queue+resend mechanism here. |
1091 RunIDMapCallbacks(&activate_callbacks_, | 1156 RunIDMapCallbacks(&activate_callbacks_, |
1092 SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED); | 1157 SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED); |
1093 RunIDMapCallbacks(&install_callbacks_, | 1158 RunIDMapCallbacks(&install_callbacks_, |
1094 SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED); | 1159 SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED); |
1095 RunIDMapCallbacks(&fetch_callbacks_, | 1160 RunIDMapCallbacks(&fetch_callbacks_, |
1096 SERVICE_WORKER_ERROR_FAILED, | 1161 SERVICE_WORKER_ERROR_FAILED, |
1097 SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK, | 1162 SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK, |
1098 ServiceWorkerResponse()); | 1163 ServiceWorkerResponse()); |
1099 RunIDMapCallbacks(&sync_callbacks_, | |
1100 SERVICE_WORKER_ERROR_FAILED); | |
1101 RunIDMapCallbacks(¬ification_click_callbacks_, | 1164 RunIDMapCallbacks(¬ification_click_callbacks_, |
1102 SERVICE_WORKER_ERROR_FAILED); | 1165 SERVICE_WORKER_ERROR_FAILED); |
1103 RunIDMapCallbacks(&push_callbacks_, | 1166 RunIDMapCallbacks(&push_callbacks_, |
1104 SERVICE_WORKER_ERROR_FAILED); | 1167 SERVICE_WORKER_ERROR_FAILED); |
1105 RunIDMapCallbacks(&geofencing_callbacks_, | 1168 RunIDMapCallbacks(&geofencing_callbacks_, |
1106 SERVICE_WORKER_ERROR_FAILED); | 1169 SERVICE_WORKER_ERROR_FAILED); |
1107 RunIDMapCallbacks(&cross_origin_connect_callbacks_, | 1170 RunIDMapCallbacks(&cross_origin_connect_callbacks_, |
1108 SERVICE_WORKER_ERROR_FAILED, | 1171 SERVICE_WORKER_ERROR_FAILED, |
1109 false); | 1172 false); |
1110 | 1173 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1147 bool handled = true; | 1210 bool handled = true; |
1148 IPC_BEGIN_MESSAGE_MAP(ServiceWorkerVersion, message) | 1211 IPC_BEGIN_MESSAGE_MAP(ServiceWorkerVersion, message) |
1149 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GetClients, | 1212 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GetClients, |
1150 OnGetClients) | 1213 OnGetClients) |
1151 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ActivateEventFinished, | 1214 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ActivateEventFinished, |
1152 OnActivateEventFinished) | 1215 OnActivateEventFinished) |
1153 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_InstallEventFinished, | 1216 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_InstallEventFinished, |
1154 OnInstallEventFinished) | 1217 OnInstallEventFinished) |
1155 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_FetchEventFinished, | 1218 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_FetchEventFinished, |
1156 OnFetchEventFinished) | 1219 OnFetchEventFinished) |
1157 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SyncEventFinished, | |
1158 OnSyncEventFinished) | |
1159 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_NotificationClickEventFinished, | 1220 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_NotificationClickEventFinished, |
1160 OnNotificationClickEventFinished) | 1221 OnNotificationClickEventFinished) |
1161 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PushEventFinished, | 1222 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PushEventFinished, |
1162 OnPushEventFinished) | 1223 OnPushEventFinished) |
1163 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GeofencingEventFinished, | 1224 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GeofencingEventFinished, |
1164 OnGeofencingEventFinished) | 1225 OnGeofencingEventFinished) |
1165 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_CrossOriginConnectEventFinished, | 1226 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_CrossOriginConnectEventFinished, |
1166 OnCrossOriginConnectEventFinished) | 1227 OnCrossOriginConnectEventFinished) |
1167 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_OpenWindow, | 1228 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_OpenWindow, |
1168 OnOpenWindow) | 1229 OnOpenWindow) |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1320 | 1381 |
1321 // TODO(kinuko): Record other event statuses too. | 1382 // TODO(kinuko): Record other event statuses too. |
1322 const bool handled = (result == SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE); | 1383 const bool handled = (result == SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE); |
1323 metrics_->RecordEventStatus(handled); | 1384 metrics_->RecordEventStatus(handled); |
1324 | 1385 |
1325 scoped_refptr<ServiceWorkerVersion> protect(this); | 1386 scoped_refptr<ServiceWorkerVersion> protect(this); |
1326 callback->Run(SERVICE_WORKER_OK, result, response); | 1387 callback->Run(SERVICE_WORKER_OK, result, response); |
1327 RemoveCallbackAndStopIfRedundant(&fetch_callbacks_, request_id); | 1388 RemoveCallbackAndStopIfRedundant(&fetch_callbacks_, request_id); |
1328 } | 1389 } |
1329 | 1390 |
1330 void ServiceWorkerVersion::OnSyncEventFinished( | |
1331 int request_id, | |
1332 blink::WebServiceWorkerEventResult result) { | |
1333 TRACE_EVENT1("ServiceWorker", | |
1334 "ServiceWorkerVersion::OnSyncEventFinished", | |
1335 "Request id", request_id); | |
1336 StatusCallback* callback = sync_callbacks_.Lookup(request_id); | |
1337 if (!callback) { | |
1338 NOTREACHED() << "Got unexpected message: " << request_id; | |
1339 return; | |
1340 } | |
1341 | |
1342 ServiceWorkerStatusCode status = SERVICE_WORKER_OK; | |
1343 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( | |
1344 switches::kEnableServiceWorkerSync)) { | |
1345 // Avoid potential race condition where flag is disabled after a sync event | |
1346 // was dispatched | |
1347 status = SERVICE_WORKER_ERROR_ABORT; | |
1348 } else if (result == blink::WebServiceWorkerEventResultRejected) { | |
1349 status = SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED; | |
1350 } | |
1351 | |
1352 scoped_refptr<ServiceWorkerVersion> protect(this); | |
1353 callback->Run(status); | |
1354 RemoveCallbackAndStopIfRedundant(&sync_callbacks_, request_id); | |
1355 } | |
1356 | |
1357 void ServiceWorkerVersion::OnNotificationClickEventFinished( | 1391 void ServiceWorkerVersion::OnNotificationClickEventFinished( |
1358 int request_id) { | 1392 int request_id) { |
1359 TRACE_EVENT1("ServiceWorker", | 1393 TRACE_EVENT1("ServiceWorker", |
1360 "ServiceWorkerVersion::OnNotificationClickEventFinished", | 1394 "ServiceWorkerVersion::OnNotificationClickEventFinished", |
1361 "Request id", request_id); | 1395 "Request id", request_id); |
1362 StatusCallback* callback = notification_click_callbacks_.Lookup(request_id); | 1396 StatusCallback* callback = notification_click_callbacks_.Lookup(request_id); |
1363 if (!callback) { | 1397 if (!callback) { |
1364 NOTREACHED() << "Got unexpected message: " << request_id; | 1398 NOTREACHED() << "Got unexpected message: " << request_id; |
1365 return; | 1399 return; |
1366 } | 1400 } |
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1891 // forcibly fail pending callbacks so no one is stuck waiting | 1925 // forcibly fail pending callbacks so no one is stuck waiting |
1892 // for the worker. | 1926 // for the worker. |
1893 embedded_worker_->StopIfIdle(); | 1927 embedded_worker_->StopIfIdle(); |
1894 } | 1928 } |
1895 | 1929 |
1896 bool ServiceWorkerVersion::HasInflightRequests() const { | 1930 bool ServiceWorkerVersion::HasInflightRequests() const { |
1897 return | 1931 return |
1898 !activate_callbacks_.IsEmpty() || | 1932 !activate_callbacks_.IsEmpty() || |
1899 !install_callbacks_.IsEmpty() || | 1933 !install_callbacks_.IsEmpty() || |
1900 !fetch_callbacks_.IsEmpty() || | 1934 !fetch_callbacks_.IsEmpty() || |
1901 !sync_callbacks_.IsEmpty() || | |
1902 !notification_click_callbacks_.IsEmpty() || | 1935 !notification_click_callbacks_.IsEmpty() || |
1903 !push_callbacks_.IsEmpty() || | 1936 !push_callbacks_.IsEmpty() || |
1904 !geofencing_callbacks_.IsEmpty() || | 1937 !geofencing_callbacks_.IsEmpty() || |
1905 !cross_origin_connect_callbacks_.IsEmpty() || | 1938 !cross_origin_connect_callbacks_.IsEmpty() || |
1906 !streaming_url_request_jobs_.empty(); | 1939 !streaming_url_request_jobs_.empty(); |
1907 } | 1940 } |
1908 | 1941 |
1909 void ServiceWorkerVersion::RecordStartWorkerResult( | 1942 void ServiceWorkerVersion::RecordStartWorkerResult( |
1910 ServiceWorkerStatusCode status) { | 1943 ServiceWorkerStatusCode status) { |
1911 base::TimeTicks start_time = start_time_; | 1944 base::TimeTicks start_time = start_time_; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1972 return RunIDMapCallback(&activate_callbacks_, info.id, | 2005 return RunIDMapCallback(&activate_callbacks_, info.id, |
1973 SERVICE_WORKER_ERROR_TIMEOUT); | 2006 SERVICE_WORKER_ERROR_TIMEOUT); |
1974 case REQUEST_INSTALL: | 2007 case REQUEST_INSTALL: |
1975 return RunIDMapCallback(&install_callbacks_, info.id, | 2008 return RunIDMapCallback(&install_callbacks_, info.id, |
1976 SERVICE_WORKER_ERROR_TIMEOUT); | 2009 SERVICE_WORKER_ERROR_TIMEOUT); |
1977 case REQUEST_FETCH: | 2010 case REQUEST_FETCH: |
1978 return RunIDMapCallback( | 2011 return RunIDMapCallback( |
1979 &fetch_callbacks_, info.id, SERVICE_WORKER_ERROR_TIMEOUT, | 2012 &fetch_callbacks_, info.id, SERVICE_WORKER_ERROR_TIMEOUT, |
1980 /* The other args are ignored for non-OK status. */ | 2013 /* The other args are ignored for non-OK status. */ |
1981 SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK, ServiceWorkerResponse()); | 2014 SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK, ServiceWorkerResponse()); |
1982 case REQUEST_SYNC: | |
1983 return RunIDMapCallback(&sync_callbacks_, info.id, | |
1984 SERVICE_WORKER_ERROR_TIMEOUT); | |
1985 case REQUEST_NOTIFICATION_CLICK: | 2015 case REQUEST_NOTIFICATION_CLICK: |
1986 return RunIDMapCallback(¬ification_click_callbacks_, info.id, | 2016 return RunIDMapCallback(¬ification_click_callbacks_, info.id, |
1987 SERVICE_WORKER_ERROR_TIMEOUT); | 2017 SERVICE_WORKER_ERROR_TIMEOUT); |
1988 case REQUEST_PUSH: | 2018 case REQUEST_PUSH: |
1989 return RunIDMapCallback(&push_callbacks_, info.id, | 2019 return RunIDMapCallback(&push_callbacks_, info.id, |
1990 SERVICE_WORKER_ERROR_TIMEOUT); | 2020 SERVICE_WORKER_ERROR_TIMEOUT); |
1991 case REQUEST_GEOFENCING: | 2021 case REQUEST_GEOFENCING: |
1992 return RunIDMapCallback(&geofencing_callbacks_, info.id, | 2022 return RunIDMapCallback(&geofencing_callbacks_, info.id, |
1993 SERVICE_WORKER_ERROR_TIMEOUT); | 2023 SERVICE_WORKER_ERROR_TIMEOUT); |
1994 case REQUEST_CROSS_ORIGIN_CONNECT: | 2024 case REQUEST_CROSS_ORIGIN_CONNECT: |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2030 return SERVICE_WORKER_ERROR_ABORT; | 2060 return SERVICE_WORKER_ERROR_ABORT; |
2031 default: | 2061 default: |
2032 return SERVICE_WORKER_ERROR_NETWORK; | 2062 return SERVICE_WORKER_ERROR_NETWORK; |
2033 } | 2063 } |
2034 } | 2064 } |
2035 | 2065 |
2036 return default_code; | 2066 return default_code; |
2037 } | 2067 } |
2038 | 2068 |
2039 } // namespace content | 2069 } // namespace content |
OLD | NEW |