Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(394)

Side by Side Diff: content/browser/service_worker/service_worker_version.cc

Issue 1171173002: [Background Sync] Use Mojo IPC to fire background sync events (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Formatting fixes Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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(&notification_click_callbacks_, 1164 RunIDMapCallbacks(&notification_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
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
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
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
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(&notification_click_callbacks_, info.id, 2016 return RunIDMapCallback(&notification_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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698