diff options
Diffstat (limited to 'chromium/content/child/navigator_connect')
5 files changed, 253 insertions, 0 deletions
diff --git a/chromium/content/child/navigator_connect/OWNERS b/chromium/content/child/navigator_connect/OWNERS new file mode 100644 index 00000000000..1b10b3436d9 --- /dev/null +++ b/chromium/content/child/navigator_connect/OWNERS @@ -0,0 +1 @@ +mek@chromium.org diff --git a/chromium/content/child/navigator_connect/navigator_connect_dispatcher.cc b/chromium/content/child/navigator_connect/navigator_connect_dispatcher.cc new file mode 100644 index 00000000000..1a30433ac81 --- /dev/null +++ b/chromium/content/child/navigator_connect/navigator_connect_dispatcher.cc @@ -0,0 +1,36 @@ +// 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/navigator_connect/navigator_connect_dispatcher.h" + +#include "content/child/navigator_connect/navigator_connect_provider.h" +#include "content/common/navigator_connect_messages.h" + +namespace content { + +NavigatorConnectDispatcher::NavigatorConnectDispatcher(ThreadSafeSender* sender) + : WorkerThreadMessageFilter(sender) { +} + +NavigatorConnectDispatcher::~NavigatorConnectDispatcher() { +} + +bool NavigatorConnectDispatcher::ShouldHandleMessage( + const IPC::Message& msg) const { + return IPC_MESSAGE_CLASS(msg) == NavigatorConnectMsgStart; +} + +void NavigatorConnectDispatcher::OnFilteredMessageReceived( + const IPC::Message& msg) { + NavigatorConnectProvider::ThreadSpecificInstance( + thread_safe_sender(), main_thread_task_runner())->OnMessageReceived(msg); +} + +bool NavigatorConnectDispatcher::GetWorkerThreadIdForMessage( + const IPC::Message& msg, + int* ipc_thread_id) { + return PickleIterator(msg).ReadInt(ipc_thread_id); +} + +} // namespace content diff --git a/chromium/content/child/navigator_connect/navigator_connect_dispatcher.h b/chromium/content/child/navigator_connect/navigator_connect_dispatcher.h new file mode 100644 index 00000000000..0044b515db6 --- /dev/null +++ b/chromium/content/child/navigator_connect/navigator_connect_dispatcher.h @@ -0,0 +1,32 @@ +// 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. + +#ifndef CONTENT_CHILD_NAVIGATOR_CONNECT_NAVIGATOR_CONNECT_DISPATCHER_H_ +#define CONTENT_CHILD_NAVIGATOR_CONNECT_NAVIGATOR_CONNECT_DISPATCHER_H_ + +#include "content/child/worker_thread_message_filter.h" + +namespace content { + +// Receives IPC messages from the browser process and dispatches them to the +// correct thread specific NavigatorConnectProvider. +class NavigatorConnectDispatcher : public WorkerThreadMessageFilter { + public: + explicit NavigatorConnectDispatcher(ThreadSafeSender* thread_safe_sender); + + private: + ~NavigatorConnectDispatcher() override; + + // WorkerThreadMessageFilter: + bool ShouldHandleMessage(const IPC::Message& msg) const override; + void OnFilteredMessageReceived(const IPC::Message& msg) override; + bool GetWorkerThreadIdForMessage(const IPC::Message& msg, + int* ipc_thread_id) override; + + DISALLOW_COPY_AND_ASSIGN(NavigatorConnectDispatcher); +}; + +} // namespace content + +#endif // CONTENT_CHILD_NAVIGATOR_CONNECT_NAVIGATOR_CONNECT_DISPATCHER_H_ diff --git a/chromium/content/child/navigator_connect/navigator_connect_provider.cc b/chromium/content/child/navigator_connect/navigator_connect_provider.cc new file mode 100644 index 00000000000..78c3fdad7fd --- /dev/null +++ b/chromium/content/child/navigator_connect/navigator_connect_provider.cc @@ -0,0 +1,104 @@ +// 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/navigator_connect/navigator_connect_provider.h" + +#include "base/lazy_instance.h" +#include "base/single_thread_task_runner.h" +#include "base/task_runner_util.h" +#include "content/child/thread_safe_sender.h" +#include "content/child/webmessageportchannel_impl.h" +#include "content/common/navigator_connect_messages.h" +#include "content/public/common/navigator_connect_client.h" +#include "third_party/WebKit/public/platform/WebURL.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, + const scoped_refptr<base::SingleThreadTaskRunner>& main_loop) + : thread_safe_sender_(thread_safe_sender), main_loop_(main_loop) { + g_provider_tls.Pointer()->Set(this); +} + +NavigatorConnectProvider::~NavigatorConnectProvider() { + g_provider_tls.Pointer()->Set(kHasBeenDeleted); +} + +void NavigatorConnectProvider::connect( + const blink::WebURL& target_url, + const blink::WebString& origin, + blink::WebNavigatorConnectPortCallbacks* callbacks) { + int request_id = requests_.Add(callbacks); + + thread_safe_sender_->Send(new NavigatorConnectHostMsg_Connect( + CurrentWorkerId(), request_id, + NavigatorConnectClient(target_url, GURL(origin), MSG_ROUTING_NONE))); +} + +void NavigatorConnectProvider::OnMessageReceived(const IPC::Message& msg) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(NavigatorConnectProvider, msg) + IPC_MESSAGE_HANDLER(NavigatorConnectMsg_ConnectResult, OnConnectResult) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + DCHECK(handled) << "Unhandled message:" << msg.type(); +} + +NavigatorConnectProvider* NavigatorConnectProvider::ThreadSpecificInstance( + ThreadSafeSender* thread_safe_sender, + const scoped_refptr<base::SingleThreadTaskRunner>& main_loop) { + 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, main_loop); + if (WorkerTaskRunner::Instance()->CurrentWorkerId()) + WorkerTaskRunner::Instance()->AddStopObserver(provider); + return provider; +} + +void NavigatorConnectProvider::OnConnectResult( + int thread_id, + int request_id, + const TransferredMessagePort& message_port, + int message_port_route_id, + bool allow_connect) { + blink::WebNavigatorConnectPortCallbacks* callbacks = + requests_.Lookup(request_id); + DCHECK(callbacks); + + if (allow_connect) { + WebMessagePortChannelImpl* channel = new WebMessagePortChannelImpl( + message_port_route_id, message_port, main_loop_); + callbacks->onSuccess(channel); + } else { + callbacks->onError(); + } + requests_.Remove(request_id); +} + +void NavigatorConnectProvider::OnWorkerRunLoopStopped() { + delete this; +} + +} // namespace content diff --git a/chromium/content/child/navigator_connect/navigator_connect_provider.h b/chromium/content/child/navigator_connect/navigator_connect_provider.h new file mode 100644 index 00000000000..f21b0c4a97e --- /dev/null +++ b/chromium/content/child/navigator_connect/navigator_connect_provider.h @@ -0,0 +1,80 @@ +// 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. + +#ifndef CONTENT_CHILD_NAVIGATOR_CONNECT_NAVIGATOR_CONNECT_PROVIDER_H_ +#define CONTENT_CHILD_NAVIGATOR_CONNECT_NAVIGATOR_CONNECT_PROVIDER_H_ + +#include "base/compiler_specific.h" +#include "base/id_map.h" +#include "base/memory/ref_counted.h" +#include "content/child/worker_task_runner.h" +#include "third_party/WebKit/public/platform/WebNavigatorConnectProvider.h" + +class GURL; + +namespace base { +class SingleThreadTaskRunner; +} + +namespace blink { +class WebMessagePortChannel; +class WebString; +} + +namespace IPC { +class Message; +} + +namespace content { +class ThreadSafeSender; +struct TransferredMessagePort; + +// Main entry point for the navigator.connect API in a child process. This +// implements the blink API and passes connect calls on to the browser process. +// NavigatorConnectDispatcher receives IPCs from the browser process and passes +// them on to the correct thread specific instance of this class. +// The ThreadSpecificInstance method will return an instance of this class for +// the current thread, or create one if no instance exists yet for this thread. +// This class deletes itself if the worker thread it belongs to quits. +class NavigatorConnectProvider : public blink::WebNavigatorConnectProvider, + public WorkerTaskRunner::Observer { + public: + NavigatorConnectProvider( + ThreadSafeSender* thread_safe_sender, + const scoped_refptr<base::SingleThreadTaskRunner>& main_loop); + ~NavigatorConnectProvider(); + + // WebNavigatorConnectProvider implementation. + virtual void connect(const blink::WebURL& target_url, + const blink::WebString& origin, + blink::WebNavigatorConnectPortCallbacks* callbacks); + + void OnMessageReceived(const IPC::Message& msg); + + // |thread_safe_sender| and |main_loop| need to be passed in because if the + // call leads to construction they will be needed. + static NavigatorConnectProvider* ThreadSpecificInstance( + ThreadSafeSender* thread_safe_sender, + const scoped_refptr<base::SingleThreadTaskRunner>& main_loop); + + private: + void OnConnectResult(int thread_id, + int request_id, + const TransferredMessagePort& message_port, + int message_port_route_id, + bool allow_connect); + + // WorkerTaskRunner::Observer implementation. + void OnWorkerRunLoopStopped() override; + + scoped_refptr<ThreadSafeSender> thread_safe_sender_; + scoped_refptr<base::SingleThreadTaskRunner> main_loop_; + IDMap<blink::WebNavigatorConnectPortCallbacks, IDMapOwnPointer> requests_; + + DISALLOW_COPY_AND_ASSIGN(NavigatorConnectProvider); +}; + +} // namespace content + +#endif // CONTENT_CHILD_NAVIGATOR_CONNECT_NAVIGATOR_CONNECT_PROVIDER_H_ |