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

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

Issue 1535983002: ServiceWorker: Factor out functions to collect client information from ServiceWorkerVersion (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 4 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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_client_navigation_utils. h" 5 #include "content/browser/service_worker/service_worker_client_utils.h"
6
7 #include <algorithm>
6 8
7 #include "base/macros.h" 9 #include "base/macros.h"
8 #include "content/browser/frame_host/frame_tree_node.h" 10 #include "content/browser/frame_host/frame_tree_node.h"
9 #include "content/browser/frame_host/render_frame_host_impl.h" 11 #include "content/browser/frame_host/render_frame_host_impl.h"
10 #include "content/browser/service_worker/service_worker_context_core.h" 12 #include "content/browser/service_worker/service_worker_context_core.h"
11 #include "content/browser/service_worker/service_worker_context_wrapper.h" 13 #include "content/browser/service_worker/service_worker_context_wrapper.h"
14 #include "content/browser/service_worker/service_worker_version.h"
12 #include "content/browser/storage_partition_impl.h" 15 #include "content/browser/storage_partition_impl.h"
13 #include "content/common/service_worker/service_worker_client_info.h" 16 #include "content/common/service_worker/service_worker_client_info.h"
17 #include "content/common/service_worker/service_worker_types.h"
14 #include "content/public/browser/browser_thread.h" 18 #include "content/public/browser/browser_thread.h"
15 #include "content/public/browser/content_browser_client.h" 19 #include "content/public/browser/content_browser_client.h"
16 #include "content/public/browser/page_navigator.h" 20 #include "content/public/browser/page_navigator.h"
17 #include "content/public/browser/web_contents.h" 21 #include "content/public/browser/web_contents.h"
18 #include "content/public/browser/web_contents_observer.h" 22 #include "content/public/browser/web_contents_observer.h"
19 #include "content/public/common/child_process_host.h" 23 #include "content/public/common/child_process_host.h"
20 #include "url/gurl.h" 24 #include "url/gurl.h"
21 25
22 namespace content { 26 namespace content {
23 namespace service_worker_client_navigation_utils { 27 namespace service_worker_client_utils {
24 28
25 namespace { 29 namespace {
26 30
27 using OpenURLCallback = base::Callback<void(int, int)>; 31 using OpenURLCallback = base::Callback<void(int, int)>;
32 using GetWindowClientsCallback =
33 base::Callback<void(scoped_ptr<ServiceWorkerClients>)>;
28 34
29 // The OpenURLObserver class is a WebContentsObserver that will wait for a 35 // The OpenURLObserver class is a WebContentsObserver that will wait for a
30 // WebContents to be initialized, run the |callback| passed to its constructor 36 // WebContents to be initialized, run the |callback| passed to its constructor
31 // then self destroy. 37 // then self destroy.
32 // The callback will receive the process and frame ids. If something went wrong 38 // The callback will receive the process and frame ids. If something went wrong
33 // those will be (kInvalidUniqueID, MSG_ROUTING_NONE). 39 // those will be (kInvalidUniqueID, MSG_ROUTING_NONE).
34 // The callback will be called in the IO thread. 40 // The callback will be called in the IO thread.
35 class OpenURLObserver : public WebContentsObserver { 41 class OpenURLObserver : public WebContentsObserver {
36 public: 42 public:
37 OpenURLObserver(WebContents* web_contents, 43 OpenURLObserver(WebContents* web_contents,
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 provider_host->GetWindowClientInfo( 199 provider_host->GetWindowClientInfo(
194 base::Bind(callback, SERVICE_WORKER_OK, provider_host->client_uuid())); 200 base::Bind(callback, SERVICE_WORKER_OK, provider_host->client_uuid()));
195 return; 201 return;
196 } 202 }
197 203
198 // If here, it means that no provider_host was found, in which case, the 204 // If here, it means that no provider_host was found, in which case, the
199 // renderer should still be informed that the window was opened. 205 // renderer should still be informed that the window was opened.
200 callback.Run(SERVICE_WORKER_OK, std::string(), ServiceWorkerClientInfo()); 206 callback.Run(SERVICE_WORKER_OK, std::string(), ServiceWorkerClientInfo());
201 } 207 }
202 208
209 void AddWindowClient(
210 ServiceWorkerProviderHost* host,
211 std::vector<base::Tuple<int, int, std::string>>* client_info) {
212 if (host->client_type() != blink::WebServiceWorkerClientTypeWindow)
213 return;
214 client_info->push_back(base::MakeTuple(host->process_id(), host->frame_id(),
215 host->client_uuid()));
216 }
217
218 void AddNonWindowClient(ServiceWorkerProviderHost* host,
219 const ServiceWorkerClientQueryOptions& options,
220 ServiceWorkerClients* clients) {
221 blink::WebServiceWorkerClientType host_client_type = host->client_type();
222 if (host_client_type == blink::WebServiceWorkerClientTypeWindow)
223 return;
224 if (options.client_type != blink::WebServiceWorkerClientTypeAll &&
225 options.client_type != host_client_type)
226 return;
227
228 ServiceWorkerClientInfo client_info(blink::WebPageVisibilityStateHidden,
229 false, // is_focused
230 host->document_url(),
231 REQUEST_CONTEXT_FRAME_TYPE_NONE,
232 base::TimeTicks(), host_client_type);
233 client_info.client_uuid = host->client_uuid();
234 clients->push_back(client_info);
235 }
236
237 void OnGetWindowClientsOnUI(
238 // The tuple contains process_id, frame_id, client_uuid.
239 const std::vector<base::Tuple<int, int, std::string>>& clients_info,
240 const GURL& script_url,
241 const GetWindowClientsCallback& callback) {
242 scoped_ptr<ServiceWorkerClients> clients(new ServiceWorkerClients);
243
244 for (const auto& it : clients_info) {
245 ServiceWorkerClientInfo info =
246 ServiceWorkerProviderHost::GetWindowClientInfoOnUI(base::get<0>(it),
247 base::get<1>(it));
248
249 // If the request to the provider_host returned an empty
250 // ServiceWorkerClientInfo, that means that it wasn't possible to associate
251 // it with a valid RenderFrameHost. It might be because the frame was killed
252 // or navigated in between.
253 if (info.IsEmpty())
254 continue;
255
256 // We can get info for a frame that was navigating end ended up with a
257 // different URL than expected. In such case, we should make sure to not
258 // expose cross-origin WindowClient.
259 if (info.url.GetOrigin() != script_url.GetOrigin())
260 continue;
261
262 info.client_uuid = base::get<2>(it);
263 clients->push_back(info);
264 }
265
266 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
267 base::Bind(callback, base::Passed(&clients)));
268 }
269
270 struct ServiceWorkerClientInfoSortMRU {
271 bool operator()(const ServiceWorkerClientInfo& a,
272 const ServiceWorkerClientInfo& b) const {
273 return a.last_focus_time > b.last_focus_time;
274 }
275 };
276
277 void DidGetClients(const ClientsCallback& callback,
278 ServiceWorkerClients* clients) {
279 DCHECK_CURRENTLY_ON(BrowserThread::IO);
280
281 // Sort clients so that the most recently active tab is in the front.
282 std::sort(clients->begin(), clients->end(), ServiceWorkerClientInfoSortMRU());
283
284 callback.Run(clients);
285 }
286
287 void GetNonWindowClients(const base::WeakPtr<ServiceWorkerVersion>& controller,
288 const ServiceWorkerClientQueryOptions& options,
289 ServiceWorkerClients* clients) {
290 if (!options.include_uncontrolled) {
291 for (auto& controllee : controller->controllee_map())
292 AddNonWindowClient(controllee.second, options, clients);
293 } else if (controller->context()) {
294 GURL origin = controller->script_url().GetOrigin();
295 for (auto it = controller->context()->GetClientProviderHostIterator(origin);
296 !it->IsAtEnd(); it->Advance()) {
297 AddNonWindowClient(it->GetProviderHost(), options, clients);
298 }
299 }
300 }
301
302 void DidGetWindowClients(const base::WeakPtr<ServiceWorkerVersion>& controller,
303 const ServiceWorkerClientQueryOptions& options,
304 const ClientsCallback& callback,
305 scoped_ptr<ServiceWorkerClients> clients) {
306 DCHECK_CURRENTLY_ON(BrowserThread::IO);
307 if (options.client_type == blink::WebServiceWorkerClientTypeAll)
308 GetNonWindowClients(controller, options, clients.get());
309 DidGetClients(callback, clients.get());
310 }
311
312 void GetWindowClients(const base::WeakPtr<ServiceWorkerVersion>& controller,
313 const ServiceWorkerClientQueryOptions& options,
314 const ClientsCallback& callback) {
315 DCHECK_CURRENTLY_ON(BrowserThread::IO);
316 DCHECK(options.client_type == blink::WebServiceWorkerClientTypeWindow ||
317 options.client_type == blink::WebServiceWorkerClientTypeAll);
318
319 std::vector<base::Tuple<int, int, std::string>> clients_info;
320 if (!options.include_uncontrolled) {
321 for (auto& controllee : controller->controllee_map())
322 AddWindowClient(controllee.second, &clients_info);
323 } else if (controller->context()) {
324 GURL origin = controller->script_url().GetOrigin();
325 for (auto it = controller->context()->GetClientProviderHostIterator(origin);
326 !it->IsAtEnd(); it->Advance()) {
327 AddWindowClient(it->GetProviderHost(), &clients_info);
328 }
329 }
330
331 if (clients_info.empty()) {
332 DidGetWindowClients(controller, options, callback,
333 make_scoped_ptr(new ServiceWorkerClients));
334 return;
335 }
336
337 BrowserThread::PostTask(
338 BrowserThread::UI, FROM_HERE,
339 base::Bind(
340 &OnGetWindowClientsOnUI, clients_info, controller->script_url(),
341 base::Bind(&DidGetWindowClients, controller, options, callback)));
342 }
343
203 } // namespace 344 } // namespace
204 345
205 void OpenWindow(const GURL& url, 346 void OpenWindow(const GURL& url,
206 const GURL& script_url, 347 const GURL& script_url,
207 int worker_process_id, 348 int worker_process_id,
208 const base::WeakPtr<ServiceWorkerContextCore>& context, 349 const base::WeakPtr<ServiceWorkerContextCore>& context,
209 const NavigationCallback& callback) { 350 const NavigationCallback& callback) {
210 DCHECK_CURRENTLY_ON(BrowserThread::IO); 351 DCHECK_CURRENTLY_ON(BrowserThread::IO);
211 BrowserThread::PostTask( 352 BrowserThread::PostTask(
212 BrowserThread::UI, FROM_HERE, 353 BrowserThread::UI, FROM_HERE,
(...skipping 10 matching lines...) Expand all
223 const base::WeakPtr<ServiceWorkerContextCore>& context, 364 const base::WeakPtr<ServiceWorkerContextCore>& context,
224 const NavigationCallback& callback) { 365 const NavigationCallback& callback) {
225 DCHECK_CURRENTLY_ON(BrowserThread::IO); 366 DCHECK_CURRENTLY_ON(BrowserThread::IO);
226 BrowserThread::PostTask( 367 BrowserThread::PostTask(
227 BrowserThread::UI, FROM_HERE, 368 BrowserThread::UI, FROM_HERE,
228 base::Bind( 369 base::Bind(
229 &NavigateClientOnUI, url, script_url, process_id, frame_id, 370 &NavigateClientOnUI, url, script_url, process_id, frame_id,
230 base::Bind(&DidNavigate, context, script_url.GetOrigin(), callback))); 371 base::Bind(&DidNavigate, context, script_url.GetOrigin(), callback)));
231 } 372 }
232 373
233 } // namespace service_worker_client_navigation_utils 374 void GetClients(const base::WeakPtr<ServiceWorkerVersion>& controller,
375 const ServiceWorkerClientQueryOptions& options,
376 const ClientsCallback& callback) {
377 DCHECK_CURRENTLY_ON(BrowserThread::IO);
378
379 ServiceWorkerClients clients;
380 if (!controller->HasControllee() && !options.include_uncontrolled) {
381 DidGetClients(callback, &clients);
382 return;
383 }
384
385 // For Window clients we want to query the info on the UI thread first.
386 if (options.client_type == blink::WebServiceWorkerClientTypeWindow ||
387 options.client_type == blink::WebServiceWorkerClientTypeAll) {
388 GetWindowClients(controller, options, callback);
389 return;
390 }
391
392 GetNonWindowClients(controller, options, &clients);
393 DidGetClients(callback, &clients);
394 }
395
396 } // namespace service_worker_client_utils
234 } // namespace content 397 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/service_worker/service_worker_client_utils.h ('k') | content/browser/service_worker/service_worker_version.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698