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

Unified Diff: content/browser/navigator_connect/navigator_connect_service_worker_service_factory.cc

Issue 861373002: Refactor navigator.connect code to make it more flexible. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix typo 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/navigator_connect/navigator_connect_service_worker_service_factory.cc
diff --git a/content/browser/navigator_connect/navigator_connect_context.cc b/content/browser/navigator_connect/navigator_connect_service_worker_service_factory.cc
similarity index 19%
rename from content/browser/navigator_connect/navigator_connect_context.cc
rename to content/browser/navigator_connect/navigator_connect_service_worker_service_factory.cc
index 45d6a6f6cf74f17072ed984b4038c4d921e8f806..1fc27f3321d158f073eda950a187e94cff6291e3 100644
--- a/content/browser/navigator_connect/navigator_connect_context.cc
+++ b/content/browser/navigator_connect/navigator_connect_service_worker_service_factory.cc
@@ -1,71 +1,96 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
+// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/browser/navigator_connect/navigator_connect_context.h"
+#include "content/browser/navigator_connect/navigator_connect_service_worker_service_factory.h"
+#include "base/bind.h"
#include "content/browser/message_port_service.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/service_worker/service_worker_utils.h"
-#include "content/common/navigator_connect_types.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/message_port_delegate.h"
+#include "content/public/common/navigator_connect_client.h"
namespace content {
-struct NavigatorConnectContext::Connection {
- CrossOriginServiceWorkerClient client;
- int64 service_worker_registration_id;
- GURL service_worker_registration_origin;
-};
+namespace {
-NavigatorConnectContext::NavigatorConnectContext(
- const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context)
- : service_worker_context_(service_worker_context) {
-}
+// MessagePortDelegate implementation that directs all messages to the
+// oncrossoriginmessage event of a service worker.
+// TODO(mek): Somehow clean up message ports when a service worker is
+// unregistered.
+class NavigatorConnectServiceWorkerService : public MessagePortDelegate {
+ public:
+ NavigatorConnectServiceWorkerService(
+ const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context,
+ const NavigatorConnectClient& client,
+ const scoped_refptr<ServiceWorkerRegistration>&
+ service_worker_registration);
+ ~NavigatorConnectServiceWorkerService() override;
+
+ // MessagePortDelegate implementation.
+ void SendMessage(int route_id,
+ const base::string16& message,
+ const std::vector<int>& sent_message_port_ids) override;
+ void SendMessagesAreQueued(int route_id) override;
+
+ private:
+ // Callback called by SendMessage when the ServiceWorkerRegistration for this
+ // service has been located.
+ void DeliverMessage(const base::string16& message,
+ const std::vector<int>& sent_message_port_ids,
+ ServiceWorkerStatusCode service_worker_status,
+ const scoped_refptr<ServiceWorkerRegistration>&
+ service_worker_registration);
+
+ scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_;
+ NavigatorConnectClient client_;
+ int64 service_worker_registration_id_;
+ GURL service_worker_registration_origin_;
-NavigatorConnectContext::~NavigatorConnectContext() {
+ base::WeakPtrFactory<NavigatorConnectServiceWorkerService> weak_factory_;
+};
+
+NavigatorConnectServiceWorkerService::NavigatorConnectServiceWorkerService(
+ const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context,
+ const NavigatorConnectClient& client,
+ const scoped_refptr<ServiceWorkerRegistration>& service_worker_registration)
+ : service_worker_context_(service_worker_context),
+ client_(client),
+ service_worker_registration_id_(service_worker_registration->id()),
+ service_worker_registration_origin_(
+ service_worker_registration->pattern().GetOrigin()),
+ weak_factory_(this) {
}
-void NavigatorConnectContext::RegisterConnection(
- const CrossOriginServiceWorkerClient& client,
- const scoped_refptr<ServiceWorkerRegistration>&
- service_worker_registration) {
- MessagePortService::GetInstance()->UpdateMessagePort(
- client.message_port_id, this, client.message_port_id);
- MessagePortService::GetInstance()->ReleaseMessages(client.message_port_id);
- Connection& connection = connections_[client.message_port_id];
- connection.client = client;
- connection.service_worker_registration_id = service_worker_registration->id();
- connection.service_worker_registration_origin =
- service_worker_registration->pattern().GetOrigin();
+NavigatorConnectServiceWorkerService::~NavigatorConnectServiceWorkerService() {
}
-void NavigatorConnectContext::SendMessage(
+void NavigatorConnectServiceWorkerService::SendMessage(
int route_id,
const base::string16& message,
const std::vector<int>& sent_message_port_ids) {
- DCHECK(connections_.find(route_id) != connections_.end());
- const Connection& connection = connections_[route_id];
+ DCHECK(route_id == client_.message_port_id);
- // Hold messages while service worker is found, activated, and message sent
- // causing ServiceWorkerScriptContext::OnCrossOriginMessageToWorker to
- // construct WebMessagePortChannelImpl instances which send
- // MessagePortHostMsg_ReleaseMessages.
+ // Hold messages on transferred message ports. Actual delivery of the message
+ // by the service can be asynchronous. When a message is delivered,
+ // WebMessagePortChannelImpl instances will be constructed which send
+ // MessagePortHostMsg_ReleaseMessages to release messages.
for (int sent_message_port_id : sent_message_port_ids)
MessagePortService::GetInstance()->HoldMessages(sent_message_port_id);
service_worker_context_->context()->storage()->FindRegistrationForId(
- connection.service_worker_registration_id,
- connection.service_worker_registration_origin,
- base::Bind(&NavigatorConnectContext::DoSendMessage, this,
- connection.client, message, sent_message_port_ids));
+ service_worker_registration_id_, service_worker_registration_origin_,
+ base::Bind(&NavigatorConnectServiceWorkerService::DeliverMessage,
+ weak_factory_.GetWeakPtr(), message, sent_message_port_ids));
}
-void NavigatorConnectContext::SendMessagesAreQueued(int route_id) {
+void NavigatorConnectServiceWorkerService::SendMessagesAreQueued(int route_id) {
NOTREACHED() << "navigator.connect endpoints should never queue messages.";
}
-void NavigatorConnectContext::DoSendMessage(
- const CrossOriginServiceWorkerClient& client,
+void NavigatorConnectServiceWorkerService::DeliverMessage(
const base::string16& message,
const std::vector<int>& sent_message_port_ids,
ServiceWorkerStatusCode service_worker_status,
@@ -84,8 +109,86 @@ void NavigatorConnectContext::DoSendMessage(
}
active_version->DispatchCrossOriginMessageEvent(
- client, message, sent_message_port_ids,
+ client_, message, sent_message_port_ids,
base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
}
+} // namespace
+
+NavigatorConnectServiceWorkerServiceFactory::
+ NavigatorConnectServiceWorkerServiceFactory(const scoped_refptr<
+ ServiceWorkerContextWrapper>& service_worker_context)
+ : service_worker_context_(service_worker_context), weak_factory_(this) {
+}
+
+NavigatorConnectServiceWorkerServiceFactory::
+ ~NavigatorConnectServiceWorkerServiceFactory() {
+}
+
+bool NavigatorConnectServiceWorkerServiceFactory::HandlesUrl(
+ const GURL& target_url) {
+ // Always return true, all URLs could potentially have a service worker, and
+ // this factory will be installed as first factory, so it will only be used
+ // if no other factory claims to handle the url.
+ return true;
+}
+
+void NavigatorConnectServiceWorkerServiceFactory::Connect(
+ const NavigatorConnectClient& client,
+ const ConnectCallback& callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ // Find the right service worker to service this connection.
+ service_worker_context_->context()->storage()->FindRegistrationForDocument(
+ client.target_url,
+ base::Bind(&NavigatorConnectServiceWorkerServiceFactory::
+ GotServiceWorkerRegistration,
+ weak_factory_.GetWeakPtr(), callback, client));
+}
+
+void NavigatorConnectServiceWorkerServiceFactory::GotServiceWorkerRegistration(
+ const ConnectCallback& callback,
+ const NavigatorConnectClient& client,
+ ServiceWorkerStatusCode status,
+ const scoped_refptr<ServiceWorkerRegistration>& registration) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ if (status != SERVICE_WORKER_OK) {
+ // No service worker found, reject connection attempt.
+ OnConnectResult(callback, client, registration, status, false);
+ return;
+ }
+
+ ServiceWorkerVersion* active_version = registration->active_version();
+ if (!active_version) {
+ // No active version, reject connection attempt.
+ OnConnectResult(callback, client, registration, status, false);
+ return;
+ }
+
+ active_version->DispatchCrossOriginConnectEvent(
+ base::Bind(&NavigatorConnectServiceWorkerServiceFactory::OnConnectResult,
+ weak_factory_.GetWeakPtr(), callback, client, registration),
+ client);
+}
+
+void NavigatorConnectServiceWorkerServiceFactory::OnConnectResult(
+ const ConnectCallback& callback,
+ const NavigatorConnectClient& client,
+ const scoped_refptr<ServiceWorkerRegistration>& service_worker_registration,
+ ServiceWorkerStatusCode status,
+ bool accept_connection) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ if (status != SERVICE_WORKER_OK || !accept_connection) {
+ callback.Run(nullptr);
+ return;
+ }
+
+ // TODO(mek): Keep track of NavigatorConnectServiceWorkerService instances and
+ // clean them up when a service worker registration is deleted.
+ callback.Run(new NavigatorConnectServiceWorkerService(
+ service_worker_context_, client, service_worker_registration));
+}
+
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698