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

Unified 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, 12 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/service_worker/service_worker_client_utils.cc
diff --git a/content/browser/service_worker/service_worker_client_navigation_utils.cc b/content/browser/service_worker/service_worker_client_utils.cc
similarity index 55%
rename from content/browser/service_worker/service_worker_client_navigation_utils.cc
rename to content/browser/service_worker/service_worker_client_utils.cc
index 5147bd12dcabdcce324dc21dabe31aeac8d04a17..26ef4d35f181bd9a43c4bb5922c5698da78e6aa3 100644
--- a/content/browser/service_worker/service_worker_client_navigation_utils.cc
+++ b/content/browser/service_worker/service_worker_client_utils.cc
@@ -2,15 +2,19 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/browser/service_worker/service_worker_client_navigation_utils.h"
+#include "content/browser/service_worker/service_worker_client_utils.h"
+
+#include <algorithm>
#include "base/macros.h"
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "content/browser/service_worker/service_worker_version.h"
#include "content/browser/storage_partition_impl.h"
#include "content/common/service_worker/service_worker_client_info.h"
+#include "content/common/service_worker/service_worker_types.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/page_navigator.h"
@@ -20,11 +24,13 @@
#include "url/gurl.h"
namespace content {
-namespace service_worker_client_navigation_utils {
+namespace service_worker_client_utils {
namespace {
using OpenURLCallback = base::Callback<void(int, int)>;
+using GetWindowClientsCallback =
+ base::Callback<void(scoped_ptr<ServiceWorkerClients>)>;
// The OpenURLObserver class is a WebContentsObserver that will wait for a
// WebContents to be initialized, run the |callback| passed to its constructor
@@ -200,6 +206,141 @@ void DidNavigate(const base::WeakPtr<ServiceWorkerContextCore>& context,
callback.Run(SERVICE_WORKER_OK, std::string(), ServiceWorkerClientInfo());
}
+void AddWindowClient(
+ ServiceWorkerProviderHost* host,
+ std::vector<base::Tuple<int, int, std::string>>* client_info) {
+ if (host->client_type() != blink::WebServiceWorkerClientTypeWindow)
+ return;
+ client_info->push_back(base::MakeTuple(host->process_id(), host->frame_id(),
+ host->client_uuid()));
+}
+
+void AddNonWindowClient(ServiceWorkerProviderHost* host,
+ const ServiceWorkerClientQueryOptions& options,
+ ServiceWorkerClients* clients) {
+ blink::WebServiceWorkerClientType host_client_type = host->client_type();
+ if (host_client_type == blink::WebServiceWorkerClientTypeWindow)
+ return;
+ if (options.client_type != blink::WebServiceWorkerClientTypeAll &&
+ options.client_type != host_client_type)
+ return;
+
+ ServiceWorkerClientInfo client_info(blink::WebPageVisibilityStateHidden,
+ false, // is_focused
+ host->document_url(),
+ REQUEST_CONTEXT_FRAME_TYPE_NONE,
+ base::TimeTicks(), host_client_type);
+ client_info.client_uuid = host->client_uuid();
+ clients->push_back(client_info);
+}
+
+void OnGetWindowClientsOnUI(
+ // The tuple contains process_id, frame_id, client_uuid.
+ const std::vector<base::Tuple<int, int, std::string>>& clients_info,
+ const GURL& script_url,
+ const GetWindowClientsCallback& callback) {
+ scoped_ptr<ServiceWorkerClients> clients(new ServiceWorkerClients);
+
+ for (const auto& it : clients_info) {
+ ServiceWorkerClientInfo info =
+ ServiceWorkerProviderHost::GetWindowClientInfoOnUI(base::get<0>(it),
+ base::get<1>(it));
+
+ // If the request to the provider_host returned an empty
+ // ServiceWorkerClientInfo, that means that it wasn't possible to associate
+ // it with a valid RenderFrameHost. It might be because the frame was killed
+ // or navigated in between.
+ if (info.IsEmpty())
+ continue;
+
+ // We can get info for a frame that was navigating end ended up with a
+ // different URL than expected. In such case, we should make sure to not
+ // expose cross-origin WindowClient.
+ if (info.url.GetOrigin() != script_url.GetOrigin())
+ continue;
+
+ info.client_uuid = base::get<2>(it);
+ clients->push_back(info);
+ }
+
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::Bind(callback, base::Passed(&clients)));
+}
+
+struct ServiceWorkerClientInfoSortMRU {
+ bool operator()(const ServiceWorkerClientInfo& a,
+ const ServiceWorkerClientInfo& b) const {
+ return a.last_focus_time > b.last_focus_time;
+ }
+};
+
+void DidGetClients(const ClientsCallback& callback,
+ ServiceWorkerClients* clients) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ // Sort clients so that the most recently active tab is in the front.
+ std::sort(clients->begin(), clients->end(), ServiceWorkerClientInfoSortMRU());
+
+ callback.Run(clients);
+}
+
+void GetNonWindowClients(const base::WeakPtr<ServiceWorkerVersion>& controller,
+ const ServiceWorkerClientQueryOptions& options,
+ ServiceWorkerClients* clients) {
+ if (!options.include_uncontrolled) {
+ for (auto& controllee : controller->controllee_map())
+ AddNonWindowClient(controllee.second, options, clients);
+ } else if (controller->context()) {
+ GURL origin = controller->script_url().GetOrigin();
+ for (auto it = controller->context()->GetClientProviderHostIterator(origin);
+ !it->IsAtEnd(); it->Advance()) {
+ AddNonWindowClient(it->GetProviderHost(), options, clients);
+ }
+ }
+}
+
+void DidGetWindowClients(const base::WeakPtr<ServiceWorkerVersion>& controller,
+ const ServiceWorkerClientQueryOptions& options,
+ const ClientsCallback& callback,
+ scoped_ptr<ServiceWorkerClients> clients) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ if (options.client_type == blink::WebServiceWorkerClientTypeAll)
+ GetNonWindowClients(controller, options, clients.get());
+ DidGetClients(callback, clients.get());
+}
+
+void GetWindowClients(const base::WeakPtr<ServiceWorkerVersion>& controller,
+ const ServiceWorkerClientQueryOptions& options,
+ const ClientsCallback& callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(options.client_type == blink::WebServiceWorkerClientTypeWindow ||
+ options.client_type == blink::WebServiceWorkerClientTypeAll);
+
+ std::vector<base::Tuple<int, int, std::string>> clients_info;
+ if (!options.include_uncontrolled) {
+ for (auto& controllee : controller->controllee_map())
+ AddWindowClient(controllee.second, &clients_info);
+ } else if (controller->context()) {
+ GURL origin = controller->script_url().GetOrigin();
+ for (auto it = controller->context()->GetClientProviderHostIterator(origin);
+ !it->IsAtEnd(); it->Advance()) {
+ AddWindowClient(it->GetProviderHost(), &clients_info);
+ }
+ }
+
+ if (clients_info.empty()) {
+ DidGetWindowClients(controller, options, callback,
+ make_scoped_ptr(new ServiceWorkerClients));
+ return;
+ }
+
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(
+ &OnGetWindowClientsOnUI, clients_info, controller->script_url(),
+ base::Bind(&DidGetWindowClients, controller, options, callback)));
+}
+
} // namespace
void OpenWindow(const GURL& url,
@@ -230,5 +371,27 @@ void NavigateClient(const GURL& url,
base::Bind(&DidNavigate, context, script_url.GetOrigin(), callback)));
}
-} // namespace service_worker_client_navigation_utils
+void GetClients(const base::WeakPtr<ServiceWorkerVersion>& controller,
+ const ServiceWorkerClientQueryOptions& options,
+ const ClientsCallback& callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ ServiceWorkerClients clients;
+ if (!controller->HasControllee() && !options.include_uncontrolled) {
+ DidGetClients(callback, &clients);
+ return;
+ }
+
+ // For Window clients we want to query the info on the UI thread first.
+ if (options.client_type == blink::WebServiceWorkerClientTypeWindow ||
+ options.client_type == blink::WebServiceWorkerClientTypeAll) {
+ GetWindowClients(controller, options, callback);
+ return;
+ }
+
+ GetNonWindowClients(controller, options, &clients);
+ DidGetClients(callback, &clients);
+}
+
+} // namespace service_worker_client_utils
} // namespace content
« 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