Index: content/browser/service_worker/navigator_connect_message_handler.cc |
diff --git a/content/browser/service_worker/navigator_connect_message_handler.cc b/content/browser/service_worker/navigator_connect_message_handler.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..476cb55b1efb9c363364dc631ac3a49ffe6435fc |
--- /dev/null |
+++ b/content/browser/service_worker/navigator_connect_message_handler.cc |
@@ -0,0 +1,124 @@ |
+// Copyright 2014 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/service_worker/navigator_connect_message_handler.h" |
+ |
+#include "content/browser/message_port_service.h" |
+#include "content/browser/service_worker/service_worker_context_core.h" |
+#include "content/browser/service_worker/service_worker_registration.h" |
+#include "content/browser/service_worker/service_worker_utils.h" |
+#include "content/common/service_worker/service_worker_types.h" |
+ |
+namespace content { |
+ |
+namespace { |
+ |
+struct QueuedMessage { |
+ base::string16 message; |
+ std::vector<int> sent_message_port_ids; |
+}; |
+ |
+} // namespace |
+ |
+struct NavigatorConnectMessageHandler::MessagePort { |
+ CrossOriginServiceWorkerClient client; |
+ int64 service_worker_registration_id; |
+ GURL service_worker_registration_origin; |
+}; |
+ |
+NavigatorConnectMessageHandler::NavigatorConnectMessageHandler( |
+ base::WeakPtr<ServiceWorkerContextCore> context) |
+ : context_(context) { |
+} |
+ |
+NavigatorConnectMessageHandler::~NavigatorConnectMessageHandler() { |
+} |
+ |
+void NavigatorConnectMessageHandler::RegisterMessagePort( |
+ const CrossOriginServiceWorkerClient& client) { |
+ const int message_port_id = client.message_port_id; |
+ MessagePortService::GetInstance()->UpdateMessagePort(message_port_id, this, |
+ message_port_id); |
+ ports_[message_port_id].client = client; |
+ ports_[message_port_id].service_worker_registration_id = |
+ kInvalidServiceWorkerRegistrationId; |
+} |
+ |
+void NavigatorConnectMessageHandler::ClearRegistration(int message_port_id) { |
+ ports_.erase(message_port_id); |
+ MessagePortService::GetInstance()->ClosePort(message_port_id); |
+} |
+ |
+void NavigatorConnectMessageHandler::SetServiceWorkerRegistation( |
+ int message_port_id, |
+ const scoped_refptr<ServiceWorkerRegistration>& |
+ service_worker_registration) { |
+ DCHECK(ports_.find(message_port_id) != ports_.end()); |
+ ports_[message_port_id].service_worker_registration_id = |
+ service_worker_registration->id(); |
+ ports_[message_port_id].service_worker_registration_origin = |
+ service_worker_registration->pattern().GetOrigin(); |
+} |
+ |
+void NavigatorConnectMessageHandler::SendMessage( |
+ int route_id, |
+ const base::string16& message, |
+ const std::vector<int>& sent_message_port_ids) { |
+ LOG(INFO) << "Sending message " << message << " to route " << route_id; |
+ DCHECK(ports_.find(route_id) != ports_.end()); |
+ // There should be no situation where messages are sent to a port before it is |
+ // associated with a service worker. |
+ const MessagePort& port = ports_[route_id]; |
+ DCHECK(port.service_worker_registration_id != |
+ kInvalidServiceWorkerRegistrationId); |
+ |
+ if (!context_) { |
+ // TODO: should just clear everything with this handler |
+ ClearRegistration(route_id); |
+ return; |
+ } |
+ |
+ for (int sent_message_port_id: sent_message_port_ids) |
+ MessagePortService::GetInstance()->HoldMessages(sent_message_port_id); |
+ |
+ context_->storage()->FindRegistrationForId( |
+ port.service_worker_registration_id, |
+ port.service_worker_registration_origin, |
+ base::Bind(&NavigatorConnectMessageHandler::DoSendMessage, |
+ base::Unretained(this), port.client, message, |
+ sent_message_port_ids)); |
+} |
+ |
+void NavigatorConnectMessageHandler::SendMessagesQueued(int route_id) { |
+ LOG(INFO) << "SendMessagesQueued for route " << route_id; |
+ // Should never be called. |
+} |
+ |
+void NavigatorConnectMessageHandler::DoSendMessage( |
+ const CrossOriginServiceWorkerClient& client, |
+ const base::string16& message, |
+ const std::vector<int>& sent_message_port_ids, |
+ ServiceWorkerStatusCode service_worker_status, |
+ const scoped_refptr<ServiceWorkerRegistration>& |
+ service_worker_registration) { |
+ LOG(INFO) << "Actually sending message " << message << " to route " |
+ << client.message_port_id; |
+ if (service_worker_status != SERVICE_WORKER_OK) { |
+ ClearRegistration(client.message_port_id); |
+ return; |
+ } |
+ |
+ ServiceWorkerVersion* active_version = |
+ service_worker_registration->active_version(); |
+ if (!active_version) { |
+ // TODO(mek): Do something when no active version exists. |
+ return; |
+ } |
+ |
+ active_version->SendCrossOriginMessage( |
+ client, message, sent_message_port_ids, |
+ base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); |
+} |
+ |
+} // namespace content |