Index: content/child/service_worker/navigator_connect_provider.cc |
diff --git a/content/child/service_worker/navigator_connect_provider.cc b/content/child/service_worker/navigator_connect_provider.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..334f6cf3132845543276bcf72fe1a3e6714ce7d1 |
--- /dev/null |
+++ b/content/child/service_worker/navigator_connect_provider.cc |
@@ -0,0 +1,92 @@ |
+// 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/child/service_worker/navigator_connect_provider.h" |
+ |
+#include "base/lazy_instance.h" |
+#include "content/child/thread_safe_sender.h" |
+#include "content/child/webmessageportchannel_impl.h" |
+#include "content/common/service_worker/service_worker_messages.h" |
+#include "third_party/WebKit/public/platform/WebCallbacks.h" |
+ |
+namespace content { |
+ |
+namespace { |
+ |
+base::LazyInstance<base::ThreadLocalPointer<NavigatorConnectProvider>>::Leaky |
+ g_provider_tls = LAZY_INSTANCE_INITIALIZER; |
+ |
+NavigatorConnectProvider* const kHasBeenDeleted = |
+ reinterpret_cast<NavigatorConnectProvider*>(0x1); |
+ |
+int CurrentWorkerId() { |
+ return WorkerTaskRunner::Instance()->CurrentWorkerId(); |
+} |
+ |
+} // namespace |
+ |
+NavigatorConnectProvider::NavigatorConnectProvider( |
+ ThreadSafeSender* thread_safe_sender) |
+ : thread_safe_sender_(thread_safe_sender) { |
+ g_provider_tls.Pointer()->Set(this); |
+} |
+ |
+NavigatorConnectProvider::~NavigatorConnectProvider() { |
+ g_provider_tls.Pointer()->Set(kHasBeenDeleted); |
+} |
+ |
+void NavigatorConnectProvider::ConnectToUrl(const GURL& targetUrl, |
+ blink::WebMessagePortChannel* port, |
+ ConnectCallback* callbacks) { |
+ int request_id = requests_.Add(callbacks); |
+ |
+ // Extract the port ID. |
+ WebMessagePortChannelImpl* webchannel = |
+ static_cast<WebMessagePortChannelImpl*>(port); |
+ |
+ int message_port_id = webchannel->message_port_id(); |
+ DCHECK(message_port_id != MSG_ROUTING_NONE); |
+ webchannel->QueueMessages(); |
+ |
+ thread_safe_sender_->Send(new ServiceWorkerHostMsg_NavigatorConnect( |
+ CurrentWorkerId(), request_id, targetUrl, message_port_id)); |
+} |
+ |
+void NavigatorConnectProvider::OnNavigatorConnectResult(int thread_id, |
+ int request_id, |
+ bool allow_connect) { |
+ ConnectCallback* callbacks = requests_.Lookup(request_id); |
+ DCHECK(callbacks); |
+ if (!callbacks) |
+ return; |
+ |
+ if (allow_connect) { |
+ callbacks->onSuccess(); |
+ } else { |
+ callbacks->onError(nullptr); |
+ } |
+ requests_.Remove(request_id); |
+} |
+ |
+NavigatorConnectProvider* NavigatorConnectProvider::ThreadSpecificInstance( |
+ ThreadSafeSender* thread_safe_sender) { |
+ if (g_provider_tls.Pointer()->Get() == kHasBeenDeleted) { |
+ NOTREACHED() << "Re-instantiating TLS NavigatorConnectProvider."; |
+ g_provider_tls.Pointer()->Set(NULL); |
+ } |
+ if (g_provider_tls.Pointer()->Get()) |
+ return g_provider_tls.Pointer()->Get(); |
+ |
+ NavigatorConnectProvider* provider = |
+ new NavigatorConnectProvider(thread_safe_sender); |
+ if (WorkerTaskRunner::Instance()->CurrentWorkerId()) |
+ WorkerTaskRunner::Instance()->AddStopObserver(provider); |
+ return provider; |
+} |
+ |
+void NavigatorConnectProvider::OnWorkerRunLoopStopped() { |
+ delete this; |
+} |
+ |
+} // namespace content |