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

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

Issue 871013003: Gather the ServiceWorker client information in the browser process. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@rfh_getvisibilitystate
Patch Set: cleanup Created 5 years, 10 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/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
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 scoped_refptr<ServiceWorkerVersion> version_;
55 // |version_| must outlive this callback.
56 ServiceWorkerVersion* version_;
57 57
58 DISALLOW_COPY_AND_ASSIGN(GetClientDocumentsCallback); 58 DISALLOW_COPY_AND_ASSIGN(GetClientDocumentsCallback);
59 }; 59 };
60 60
61 namespace { 61 namespace {
62 62
63 // Default delay for scheduled stop. 63 // Default delay for scheduled stop.
64 // (Note that if all references to the version is dropped the worker 64 // (Note that if all references to the version is dropped the worker
65 // is also stopped without delay) 65 // is also stopped without delay)
66 const int64 kStopWorkerDelay = 30; // 30 secs. 66 const int64 kStopWorkerDelay = 30; // 30 secs.
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after
599 &new_routing_ids); 599 &new_routing_ids);
600 ServiceWorkerStatusCode status = 600 ServiceWorkerStatusCode status =
601 embedded_worker_->SendMessage(ServiceWorkerMsg_CrossOriginMessageToWorker( 601 embedded_worker_->SendMessage(ServiceWorkerMsg_CrossOriginMessageToWorker(
602 client, message, sent_message_port_ids, new_routing_ids)); 602 client, message, sent_message_port_ids, new_routing_ids));
603 RunSoon(base::Bind(callback, status)); 603 RunSoon(base::Bind(callback, status));
604 } 604 }
605 void ServiceWorkerVersion::AddControllee( 605 void ServiceWorkerVersion::AddControllee(
606 ServiceWorkerProviderHost* provider_host) { 606 ServiceWorkerProviderHost* provider_host) {
607 DCHECK(!ContainsKey(controllee_map_, provider_host)); 607 DCHECK(!ContainsKey(controllee_map_, provider_host));
608 int controllee_id = controllee_by_id_.Add(provider_host); 608 int controllee_id = controllee_by_id_.Add(provider_host);
609 // IDMap<>'s last index is kInvalidServiceWorkerClientId.
610 CHECK(controllee_id != kInvalidServiceWorkerClientId);
609 controllee_map_[provider_host] = controllee_id; 611 controllee_map_[provider_host] = controllee_id;
610 // Reset the timer if it's running (so that it's kept alive a bit longer 612 // Reset the timer if it's running (so that it's kept alive a bit longer
611 // right after a new controllee is added). 613 // right after a new controllee is added).
612 ScheduleStopWorker(); 614 ScheduleStopWorker();
613 } 615 }
614 616
615 void ServiceWorkerVersion::RemoveControllee( 617 void ServiceWorkerVersion::RemoveControllee(
616 ServiceWorkerProviderHost* provider_host) { 618 ServiceWorkerProviderHost* provider_host) {
617 ControlleeMap::iterator found = controllee_map_.find(provider_host); 619 ControlleeMap::iterator found = controllee_map_.find(provider_host);
618 DCHECK(found != controllee_map_.end()); 620 DCHECK(found != controllee_map_.end());
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
709 SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK, 711 SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK,
710 ServiceWorkerResponse()); 712 ServiceWorkerResponse());
711 RunIDMapCallbacks(&sync_callbacks_, 713 RunIDMapCallbacks(&sync_callbacks_,
712 SERVICE_WORKER_ERROR_FAILED); 714 SERVICE_WORKER_ERROR_FAILED);
713 RunIDMapCallbacks(&notification_click_callbacks_, 715 RunIDMapCallbacks(&notification_click_callbacks_,
714 SERVICE_WORKER_ERROR_FAILED); 716 SERVICE_WORKER_ERROR_FAILED);
715 RunIDMapCallbacks(&push_callbacks_, 717 RunIDMapCallbacks(&push_callbacks_,
716 SERVICE_WORKER_ERROR_FAILED); 718 SERVICE_WORKER_ERROR_FAILED);
717 RunIDMapCallbacks(&geofencing_callbacks_, 719 RunIDMapCallbacks(&geofencing_callbacks_,
718 SERVICE_WORKER_ERROR_FAILED); 720 SERVICE_WORKER_ERROR_FAILED);
719 RunIDMapCallbacks(&get_client_info_callbacks_,
720 SERVICE_WORKER_ERROR_FAILED,
721 ServiceWorkerClientInfo());
722 RunIDMapCallbacks(&cross_origin_connect_callbacks_, 721 RunIDMapCallbacks(&cross_origin_connect_callbacks_,
723 SERVICE_WORKER_ERROR_FAILED, 722 SERVICE_WORKER_ERROR_FAILED,
724 false); 723 false);
725 724
726 streaming_url_request_jobs_.clear(); 725 streaming_url_request_jobs_.clear();
727 726
728 FOR_EACH_OBSERVER(Listener, listeners_, OnWorkerStopped(this)); 727 FOR_EACH_OBSERVER(Listener, listeners_, OnWorkerStopped(this));
729 728
730 // There should be no more communication from/to a stopped worker. Deleting 729 // There should be no more communication from/to a stopped worker. Deleting
731 // the listener prevents any pending completion callbacks from causing 730 // the listener prevents any pending completion callbacks from causing
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
787 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PushEventFinished, 786 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PushEventFinished,
788 OnPushEventFinished) 787 OnPushEventFinished)
789 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GeofencingEventFinished, 788 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GeofencingEventFinished,
790 OnGeofencingEventFinished) 789 OnGeofencingEventFinished)
791 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_CrossOriginConnectEventFinished, 790 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_CrossOriginConnectEventFinished,
792 OnCrossOriginConnectEventFinished) 791 OnCrossOriginConnectEventFinished)
793 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessageToDocument, 792 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessageToDocument,
794 OnPostMessageToDocument) 793 OnPostMessageToDocument)
795 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_FocusClient, 794 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_FocusClient,
796 OnFocusClient) 795 OnFocusClient)
797 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GetClientInfoSuccess,
798 OnGetClientInfoSuccess)
799 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GetClientInfoError,
800 OnGetClientInfoError)
801 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SkipWaiting, 796 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SkipWaiting,
802 OnSkipWaiting) 797 OnSkipWaiting)
803 IPC_MESSAGE_UNHANDLED(handled = false) 798 IPC_MESSAGE_UNHANDLED(handled = false)
804 IPC_END_MESSAGE_MAP() 799 IPC_END_MESSAGE_MAP()
805 return handled; 800 return handled;
806 } 801 }
807 802
808 void ServiceWorkerVersion::OnStartMessageSent( 803 void ServiceWorkerVersion::OnStartMessageSent(
809 ServiceWorkerStatusCode status) { 804 ServiceWorkerStatusCode status) {
810 if (status != SERVICE_WORKER_OK) 805 if (status != SERVICE_WORKER_OK)
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
848 std::vector<ServiceWorkerClientInfo>())); 843 std::vector<ServiceWorkerClientInfo>()));
849 } 844 }
850 return; 845 return;
851 } 846 }
852 scoped_refptr<GetClientDocumentsCallback> callback( 847 scoped_refptr<GetClientDocumentsCallback> callback(
853 new GetClientDocumentsCallback(request_id, this)); 848 new GetClientDocumentsCallback(request_id, this));
854 ControlleeByIDMap::iterator it(&controllee_by_id_); 849 ControlleeByIDMap::iterator it(&controllee_by_id_);
855 TRACE_EVENT0("ServiceWorker", 850 TRACE_EVENT0("ServiceWorker",
856 "ServiceWorkerVersion::OnGetClientDocuments"); 851 "ServiceWorkerVersion::OnGetClientDocuments");
857 while (!it.IsAtEnd()) { 852 while (!it.IsAtEnd()) {
858 int client_request_id = get_client_info_callbacks_.Add( 853 // TODO(mlamouri): we could coalesce those requests into one.
859 new GetClientInfoCallback(base::Bind( 854 it.GetCurrentValue()->GetClientInfo(
860 &ServiceWorkerVersion::DidGetClientInfo, 855 base::Bind(&ServiceWorkerVersion::DidGetClientInfo,
861 weak_factory_.GetWeakPtr(), it.GetCurrentKey(), callback))); 856 weak_factory_.GetWeakPtr(), it.GetCurrentKey(), callback));
862 it.GetCurrentValue()->GetClientInfo(embedded_worker_->embedded_worker_id(),
863 client_request_id);
864 it.Advance(); 857 it.Advance();
865 } 858 }
866 } 859 }
867 860
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( 861 void ServiceWorkerVersion::OnActivateEventFinished(
893 int request_id, 862 int request_id,
894 blink::WebServiceWorkerEventResult result) { 863 blink::WebServiceWorkerEventResult result) {
895 DCHECK(ACTIVATING == status() || 864 DCHECK(ACTIVATING == status() ||
896 REDUNDANT == status()) << status(); 865 REDUNDANT == status()) << status();
897 TRACE_EVENT0("ServiceWorker", 866 TRACE_EVENT0("ServiceWorker",
898 "ServiceWorkerVersion::OnActivateEventFinished"); 867 "ServiceWorkerVersion::OnActivateEventFinished");
899 868
900 StatusCallback* callback = activate_callbacks_.Lookup(request_id); 869 StatusCallback* callback = activate_callbacks_.Lookup(request_id);
901 if (!callback) { 870 if (!callback) {
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
1101 } 1070 }
1102 1071
1103 void ServiceWorkerVersion::DidSkipWaiting(int request_id) { 1072 void ServiceWorkerVersion::DidSkipWaiting(int request_id) {
1104 if (running_status() == STARTING || running_status() == RUNNING) 1073 if (running_status() == STARTING || running_status() == RUNNING)
1105 embedded_worker_->SendMessage(ServiceWorkerMsg_DidSkipWaiting(request_id)); 1074 embedded_worker_->SendMessage(ServiceWorkerMsg_DidSkipWaiting(request_id));
1106 } 1075 }
1107 1076
1108 void ServiceWorkerVersion::DidGetClientInfo( 1077 void ServiceWorkerVersion::DidGetClientInfo(
1109 int client_id, 1078 int client_id,
1110 scoped_refptr<GetClientDocumentsCallback> callback, 1079 scoped_refptr<GetClientDocumentsCallback> callback,
1111 ServiceWorkerStatusCode status,
1112 const ServiceWorkerClientInfo& info) { 1080 const ServiceWorkerClientInfo& info) {
1113 if (status == SERVICE_WORKER_OK) 1081 // If the request to the provider_host returned an empty
1114 callback->AddClientInfo(client_id, info); 1082 // ServiceWorkerClientInfo, that means that it wasn't possible to associate
1083 // it with a valid RenderFrameHost. It might be because the frame was killed
1084 // or navigated in between.
1085 if (info.IsEmpty())
1086 return;
1087
1088 // We can get info for a frame that was navigating end ended up with a
1089 // different URL than expected. In such case, we should make sure to not
1090 // expose cross-origin WindowClient.
1091 if (info.url.GetOrigin() != script_url_.GetOrigin())
1092 return;
1093
1094 callback->AddClientInfo(client_id, info);
1115 } 1095 }
1116 1096
1117 void ServiceWorkerVersion::ScheduleStopWorker() { 1097 void ServiceWorkerVersion::ScheduleStopWorker() {
1118 if (running_status() != RUNNING) 1098 if (running_status() != RUNNING)
1119 return; 1099 return;
1120 stop_worker_timer_.Stop(); 1100 stop_worker_timer_.Stop();
1121 stop_worker_timer_.Start( 1101 stop_worker_timer_.Start(
1122 FROM_HERE, base::TimeDelta::FromSeconds( 1102 FROM_HERE, base::TimeDelta::FromSeconds(
1123 is_doomed_ ? kStopDoomedWorkerDelay : kStopWorkerDelay), 1103 is_doomed_ ? kStopDoomedWorkerDelay : kStopWorkerDelay),
1124 base::Bind(&ServiceWorkerVersion::StopWorkerIfIdle, 1104 base::Bind(&ServiceWorkerVersion::StopWorkerIfIdle,
(...skipping 17 matching lines...) Expand all
1142 1122
1143 bool ServiceWorkerVersion::HasInflightRequests() const { 1123 bool ServiceWorkerVersion::HasInflightRequests() const {
1144 return 1124 return
1145 !activate_callbacks_.IsEmpty() || 1125 !activate_callbacks_.IsEmpty() ||
1146 !install_callbacks_.IsEmpty() || 1126 !install_callbacks_.IsEmpty() ||
1147 !fetch_callbacks_.IsEmpty() || 1127 !fetch_callbacks_.IsEmpty() ||
1148 !sync_callbacks_.IsEmpty() || 1128 !sync_callbacks_.IsEmpty() ||
1149 !notification_click_callbacks_.IsEmpty() || 1129 !notification_click_callbacks_.IsEmpty() ||
1150 !push_callbacks_.IsEmpty() || 1130 !push_callbacks_.IsEmpty() ||
1151 !geofencing_callbacks_.IsEmpty() || 1131 !geofencing_callbacks_.IsEmpty() ||
1152 !get_client_info_callbacks_.IsEmpty() ||
1153 !cross_origin_connect_callbacks_.IsEmpty() || 1132 !cross_origin_connect_callbacks_.IsEmpty() ||
1154 !streaming_url_request_jobs_.empty(); 1133 !streaming_url_request_jobs_.empty();
1155 } 1134 }
1156 1135
1157 void ServiceWorkerVersion::DoomInternal() { 1136 void ServiceWorkerVersion::DoomInternal() {
1158 DCHECK(is_doomed_); 1137 DCHECK(is_doomed_);
1159 DCHECK(!HasControllee()); 1138 DCHECK(!HasControllee());
1160 SetStatus(REDUNDANT); 1139 SetStatus(REDUNDANT);
1161 StopWorkerIfIdle(); 1140 StopWorkerIfIdle();
1162 if (!context_) 1141 if (!context_)
1163 return; 1142 return;
1164 std::vector<ServiceWorkerDatabase::ResourceRecord> resources; 1143 std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
1165 script_cache_map_.GetResources(&resources); 1144 script_cache_map_.GetResources(&resources);
1166 context_->storage()->PurgeResources(resources); 1145 context_->storage()->PurgeResources(resources);
1167 } 1146 }
1168 1147
1169 template <typename IDMAP> 1148 template <typename IDMAP>
1170 void ServiceWorkerVersion::RemoveCallbackAndStopIfDoomed( 1149 void ServiceWorkerVersion::RemoveCallbackAndStopIfDoomed(
1171 IDMAP* callbacks, 1150 IDMAP* callbacks,
1172 int request_id) { 1151 int request_id) {
1173 callbacks->Remove(request_id); 1152 callbacks->Remove(request_id);
1174 if (is_doomed_) { 1153 if (is_doomed_) {
1175 // The stop should be already scheduled, but try to stop immediately, in 1154 // The stop should be already scheduled, but try to stop immediately, in
1176 // order to release worker resources soon. 1155 // order to release worker resources soon.
1177 StopWorkerIfIdle(); 1156 StopWorkerIfIdle();
1178 } 1157 }
1179 } 1158 }
1180 1159
1181 } // namespace content 1160 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/service_worker/service_worker_version.h ('k') | content/child/service_worker/service_worker_dispatcher.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698