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

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

Issue 843583005: [ServiceWorker] Implement WebServiceWorkerContextClient::openWindow(). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@content_browser_client_openurl
Patch Set: Created 5 years, 11 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"
11 #include "content/browser/message_port_message_filter.h" 11 #include "content/browser/message_port_message_filter.h"
12 #include "content/browser/message_port_service.h" 12 #include "content/browser/message_port_service.h"
13 #include "content/browser/service_worker/embedded_worker_instance.h" 13 #include "content/browser/service_worker/embedded_worker_instance.h"
14 #include "content/browser/service_worker/embedded_worker_registry.h" 14 #include "content/browser/service_worker/embedded_worker_registry.h"
15 #include "content/browser/service_worker/service_worker_context_core.h" 15 #include "content/browser/service_worker/service_worker_context_core.h"
16 #include "content/browser/service_worker/service_worker_context_wrapper.h"
16 #include "content/browser/service_worker/service_worker_registration.h" 17 #include "content/browser/service_worker/service_worker_registration.h"
17 #include "content/browser/service_worker/service_worker_utils.h" 18 #include "content/browser/service_worker/service_worker_utils.h"
19 #include "content/browser/storage_partition_impl.h"
18 #include "content/common/service_worker/service_worker_messages.h" 20 #include "content/common/service_worker/service_worker_messages.h"
19 #include "content/public/browser/browser_thread.h" 21 #include "content/public/browser/browser_thread.h"
22 #include "content/public/browser/content_browser_client.h"
23 #include "content/public/browser/page_navigator.h"
24 #include "content/public/browser/render_frame_host.h"
25 #include "content/public/browser/render_process_host.h"
26 #include "content/public/browser/web_contents.h"
27 #include "content/public/browser/web_contents_observer.h"
28 #include "content/public/common/child_process_host.h"
29 #include "content/public/common/content_client.h"
20 #include "content/public/common/content_switches.h" 30 #include "content/public/common/content_switches.h"
21 31
22 namespace content { 32 namespace content {
23 33
24 typedef ServiceWorkerVersion::StatusCallback StatusCallback; 34 typedef ServiceWorkerVersion::StatusCallback StatusCallback;
25 typedef ServiceWorkerVersion::MessageCallback MessageCallback; 35 typedef ServiceWorkerVersion::MessageCallback MessageCallback;
26 36
27 class ServiceWorkerVersion::GetClientDocumentsCallback 37 class ServiceWorkerVersion::GetClientDocumentsCallback
28 : public base::RefCounted<GetClientDocumentsCallback> { 38 : public base::RefCounted<GetClientDocumentsCallback> {
29 public: 39 public:
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 } 146 }
137 callback.Run(status); 147 callback.Run(status);
138 } 148 }
139 149
140 void RunErrorCrossOriginConnectCallback( 150 void RunErrorCrossOriginConnectCallback(
141 const ServiceWorkerVersion::CrossOriginConnectCallback& callback, 151 const ServiceWorkerVersion::CrossOriginConnectCallback& callback,
142 ServiceWorkerStatusCode status) { 152 ServiceWorkerStatusCode status) {
143 callback.Run(status, false); 153 callback.Run(status, false);
144 } 154 }
145 155
156 using WindowOpenedCallback = base::Callback<void(int,int)>;
157
158 // The WindowOpenedObserver class is a WebContentsObserver that will wait for a
159 // new Window's WebContents to be initialized, run the |callback| passed to its
160 // constructor then self destroy.
161 // The callback will receive the process and frame ids. If something went wrong
162 // those will be (kInvalidUniqueID,MSG_ROUTING_NONE).
163 class WindowOpenedObserver : public WebContentsObserver {
164 public:
165 WindowOpenedObserver(WebContents* web_contents,
166 const WindowOpenedCallback& callback)
167 : WebContentsObserver(web_contents)
168 , callback_(callback)
169 {}
170
171 void DocumentAvailableInMainFrame() override {
172 DCHECK(web_contents());
173
174 RenderFrameHost* render_frame_host = web_contents()->GetMainFrame();
175 DCHECK(render_frame_host);
176
177 RunCallback(render_frame_host->GetProcess()->GetID(),
178 render_frame_host->GetRoutingID());
179 }
180
181 void RenderProcessGone(base::TerminationStatus status) override {
182 RunCallback(ChildProcessHost::kInvalidUniqueID, MSG_ROUTING_NONE);
183 }
184
185 void WebContentsDestroyed() override {
186 RunCallback(ChildProcessHost::kInvalidUniqueID, MSG_ROUTING_NONE);
187 }
188
189 private:
190 void RunCallback(int render_process_id, int render_frame_id) {
191 // After running the callback, |this| will stop observing, thus
192 // web_contents() should return nullptr and |RunCallback| should no longer
193 // be called. Then, |this| will self destroy.
194 DCHECK(web_contents());
195
196 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
197 base::Bind(callback_,
198 render_process_id,
199 render_frame_id));
200 Observe(nullptr);
201 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
202 }
203
204 const WindowOpenedCallback callback_;
205 };
206
207 void OpenWindowOnUI(
208 const GURL& url,
209 const GURL& referrer,
210 const scoped_refptr<ServiceWorkerContextWrapper>& context_wrapper,
211 const WindowOpenedCallback& callback) {
212 DCHECK_CURRENTLY_ON(BrowserThread::UI);
213
214 BrowserContext* browser_context = context_wrapper->storage_partition()
215 ? context_wrapper->storage_partition()->browser_context()
216 : nullptr;
217 // We are shutting down.
218 if (!browser_context)
219 return;
220
221 OpenURLParams params(url,
222 Referrer(referrer, blink::WebReferrerPolicyDefault),
223 NEW_FOREGROUND_TAB,
224 ui::PAGE_TRANSITION_AUTO_TOPLEVEL,
225 false);
226 WebContents* web_contents =
227 GetContentClient()->browser()->OpenURL(browser_context, params);
michaeln 2015/01/17 00:25:32 imo, storage_partition ptr would make sense as an
michaeln 2015/01/17 00:25:32 can this method return nullptr for a web_contents,
mlamouri (slow - plz ping) 2015/01/26 13:19:08 Let's discuss about that in the CL related to Cont
228
229 new WindowOpenedObserver(web_contents, callback);
230 }
231
146 } // namespace 232 } // namespace
147 233
148 ServiceWorkerVersion::ServiceWorkerVersion( 234 ServiceWorkerVersion::ServiceWorkerVersion(
149 ServiceWorkerRegistration* registration, 235 ServiceWorkerRegistration* registration,
150 const GURL& script_url, 236 const GURL& script_url,
151 int64 version_id, 237 int64 version_id,
152 base::WeakPtr<ServiceWorkerContextCore> context) 238 base::WeakPtr<ServiceWorkerContextCore> context)
153 : version_id_(version_id), 239 : version_id_(version_id),
154 registration_id_(kInvalidServiceWorkerVersionId), 240 registration_id_(kInvalidServiceWorkerVersionId),
155 script_url_(script_url), 241 script_url_(script_url),
(...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after
781 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SyncEventFinished, 867 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SyncEventFinished,
782 OnSyncEventFinished) 868 OnSyncEventFinished)
783 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_NotificationClickEventFinished, 869 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_NotificationClickEventFinished,
784 OnNotificationClickEventFinished) 870 OnNotificationClickEventFinished)
785 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PushEventFinished, 871 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PushEventFinished,
786 OnPushEventFinished) 872 OnPushEventFinished)
787 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GeofencingEventFinished, 873 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GeofencingEventFinished,
788 OnGeofencingEventFinished) 874 OnGeofencingEventFinished)
789 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_CrossOriginConnectEventFinished, 875 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_CrossOriginConnectEventFinished,
790 OnCrossOriginConnectEventFinished) 876 OnCrossOriginConnectEventFinished)
877 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_OpenWindow,
878 OnOpenWindow)
791 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessageToDocument, 879 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessageToDocument,
792 OnPostMessageToDocument) 880 OnPostMessageToDocument)
793 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_FocusClient, 881 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_FocusClient,
794 OnFocusClient) 882 OnFocusClient)
795 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GetClientInfoSuccess, 883 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GetClientInfoSuccess,
michaeln 2015/01/17 00:25:32 Hmmm... This is not new, but these two ClientInfo
mlamouri (slow - plz ping) 2015/01/26 13:19:08 I've changed how this is being handled in https://
796 OnGetClientInfoSuccess) 884 OnGetClientInfoSuccess)
797 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GetClientInfoError, 885 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GetClientInfoError,
798 OnGetClientInfoError) 886 OnGetClientInfoError)
799 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SkipWaiting, 887 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SkipWaiting,
800 OnSkipWaiting) 888 OnSkipWaiting)
801 IPC_MESSAGE_UNHANDLED(handled = false) 889 IPC_MESSAGE_UNHANDLED(handled = false)
802 IPC_END_MESSAGE_MAP() 890 IPC_END_MESSAGE_MAP()
803 return handled; 891 return handled;
804 } 892 }
805 893
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
1031 if (!callback) { 1119 if (!callback) {
1032 NOTREACHED() << "Got unexpected message: " << request_id; 1120 NOTREACHED() << "Got unexpected message: " << request_id;
1033 return; 1121 return;
1034 } 1122 }
1035 1123
1036 scoped_refptr<ServiceWorkerVersion> protect(this); 1124 scoped_refptr<ServiceWorkerVersion> protect(this);
1037 callback->Run(SERVICE_WORKER_OK, accept_connection); 1125 callback->Run(SERVICE_WORKER_OK, accept_connection);
1038 cross_origin_connect_callbacks_.Remove(request_id); 1126 cross_origin_connect_callbacks_.Remove(request_id);
1039 } 1127 }
1040 1128
1129 void ServiceWorkerVersion::OnOpenWindow(
1130 int request_id, const GURL& url, const GURL& referrer) {
1131 // Just abort if we are shutting down.
1132 if (!context_)
1133 return;
1134 scoped_refptr<ServiceWorkerContextWrapper> context_wrapper(
1135 context_->wrapper());
1136
1137 BrowserThread::PostTask(
1138 BrowserThread::UI, FROM_HERE,
1139 base::Bind(&OpenWindowOnUI,
1140 url,
1141 referrer,
1142 context_wrapper,
michaeln 2015/01/17 00:25:32 nit: make_scoped_refptr(context_->wrapper()) might
mlamouri (slow - plz ping) 2015/01/26 13:19:08 Done.
1143 base::Bind(&ServiceWorkerVersion::DidOpenWindow,
1144 weak_factory_.GetWeakPtr(),
1145 request_id)));
1146 }
1147
1148 void ServiceWorkerVersion::DidOpenWindow(int request_id,
1149 int render_process_id,
1150 int render_frame_id) {
1151 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1152
1153 if (running_status() != RUNNING)
1154 return;
1155
1156 if (render_process_id == ChildProcessHost::kInvalidUniqueID &&
nasko 2015/01/17 00:05:28 RenderProcessHost is what hosts Blink renderers. C
mlamouri (slow - plz ping) 2015/01/26 13:19:08 My understanding was that a RenderProcess was a ty
1157 render_frame_id == MSG_ROUTING_NONE) {
1158 embedded_worker_->SendMessage(ServiceWorkerMsg_OpenWindowError(request_id));
1159 return;
1160 }
1161
1162 for (const auto& it : controllee_map_) {
1163 const ServiceWorkerProviderHost* provider_host = it.first;
1164 if (provider_host->process_id() != render_process_id ||
1165 provider_host->frame_id() != render_frame_id) {
1166 continue;
1167 }
1168
1169 int client_request_id = get_client_info_callbacks_.Add(
1170 new GetClientInfoCallback(base::Bind(
1171 &ServiceWorkerVersion::OnOpenWindowFinished,
1172 weak_factory_.GetWeakPtr(), request_id)));
1173 provider_host->GetClientInfo(embedded_worker_->embedded_worker_id(),
1174 client_request_id);
1175 return;
1176 }
1177
1178 // If here, it means that no provider_host was found, in which case, the
1179 // renderer should still be informed that the window was opened.
1180 OnOpenWindowFinished(request_id,
1181 SERVICE_WORKER_ERROR_FAILED,
1182 ServiceWorkerClientInfo());
1183 }
1184
1185 void ServiceWorkerVersion::OnOpenWindowFinished(
1186 int request_id,
1187 ServiceWorkerStatusCode status,
1188 const ServiceWorkerClientInfo& client_info) {
michaeln 2015/01/17 00:25:32 how is the client_info.client_id field filled in,
mlamouri (slow - plz ping) 2015/01/26 13:19:08 Fixed.
1189 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1190
1191 if (running_status() != RUNNING)
1192 return;
1193
1194 // If the status is an error, it means that it wasn't possible to find the
1195 // client but the window was correctly opened. In that case, the renderer is
1196 // expecting to receive the |client_info| with the boolean (|dummy_client|)
1197 // set to true.
1198 if (status != SERVICE_WORKER_OK) {
1199 embedded_worker_->SendMessage(ServiceWorkerMsg_OpenWindowResponse(
1200 request_id, client_info, true));
1201 return;
1202 }
1203
1204 embedded_worker_->SendMessage(ServiceWorkerMsg_OpenWindowResponse(
1205 request_id, client_info, false));
1206 }
1207
1041 void ServiceWorkerVersion::OnPostMessageToDocument( 1208 void ServiceWorkerVersion::OnPostMessageToDocument(
1042 int client_id, 1209 int client_id,
1043 const base::string16& message, 1210 const base::string16& message,
1044 const std::vector<int>& sent_message_port_ids) { 1211 const std::vector<int>& sent_message_port_ids) {
1045 TRACE_EVENT1("ServiceWorker", 1212 TRACE_EVENT1("ServiceWorker",
1046 "ServiceWorkerVersion::OnPostMessageToDocument", 1213 "ServiceWorkerVersion::OnPostMessageToDocument",
1047 "Client id", client_id); 1214 "Client id", client_id);
1048 ServiceWorkerProviderHost* provider_host = 1215 ServiceWorkerProviderHost* provider_host =
1049 controllee_by_id_.Lookup(client_id); 1216 controllee_by_id_.Lookup(client_id);
1050 if (!provider_host) { 1217 if (!provider_host) {
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1158 SetStatus(REDUNDANT); 1325 SetStatus(REDUNDANT);
1159 StopWorkerIfIdle(); 1326 StopWorkerIfIdle();
1160 if (!context_) 1327 if (!context_)
1161 return; 1328 return;
1162 std::vector<ServiceWorkerDatabase::ResourceRecord> resources; 1329 std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
1163 script_cache_map_.GetResources(&resources); 1330 script_cache_map_.GetResources(&resources);
1164 context_->storage()->PurgeResources(resources); 1331 context_->storage()->PurgeResources(resources);
1165 } 1332 }
1166 1333
1167 } // namespace content 1334 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698