diff options
Diffstat (limited to 'chrome/browser/extensions/api/messaging/native_message_port.cc')
-rw-r--r-- | chrome/browser/extensions/api/messaging/native_message_port.cc | 109 |
1 files changed, 101 insertions, 8 deletions
diff --git a/chrome/browser/extensions/api/messaging/native_message_port.cc b/chrome/browser/extensions/api/messaging/native_message_port.cc index a0a47d5..66b1674 100644 --- a/chrome/browser/extensions/api/messaging/native_message_port.cc +++ b/chrome/browser/extensions/api/messaging/native_message_port.cc @@ -5,27 +5,120 @@ #include "chrome/browser/extensions/api/messaging/native_message_port.h" #include "base/bind.h" +#include "base/single_thread_task_runner.h" #include "chrome/browser/extensions/api/messaging/native_message_process_host.h" #include "content/public/browser/browser_thread.h" namespace extensions { -NativeMessagePort::NativeMessagePort(NativeMessageProcessHost* native_process) - : native_process_(native_process) { +// Handles jumping between the |host_task_runner| and the +// |message_service_task_runner|. +// All methods on the host interface should be called on |host_task_runner|. +// All methods on |port| (that calls into MessageServices) should be called +// on |message_service_task_runner|. +class NativeMessagePort::Core : public NativeMessageHost::Client { + public: + Core( + scoped_ptr<NativeMessageHost> host, + base::WeakPtr<NativeMessagePort> port, + scoped_refptr<base::SingleThreadTaskRunner> message_service_task_runner_); + virtual ~Core(); + + void OnMessageFromChrome(const std::string& message); + + // NativeMessageHost::Client implementation. + virtual void PostMessageFromNativeHost(const std::string& message) OVERRIDE; + virtual void CloseChannel(const std::string& error_message) OVERRIDE; + + private: + scoped_ptr<NativeMessageHost> host_; + base::WeakPtr<NativeMessagePort> port_; + + scoped_refptr<base::SingleThreadTaskRunner> message_service_task_runner_; + scoped_refptr<base::SingleThreadTaskRunner> host_task_runner_; +}; + +NativeMessagePort::Core::Core( + scoped_ptr<NativeMessageHost> host, + base::WeakPtr<NativeMessagePort> port, + scoped_refptr<base::SingleThreadTaskRunner> message_service_task_runner) + : host_(host.Pass()), + port_(port), + message_service_task_runner_(message_service_task_runner), + host_task_runner_(host_->task_runner()) { + DCHECK(message_service_task_runner_->BelongsToCurrentThread()); + host_task_runner_->PostTask(FROM_HERE, + base::Bind(&NativeMessageHost::Start, + base::Unretained(host_.get()), + base::Unretained(this))); +} + +NativeMessagePort::Core::~Core() { + DCHECK(host_task_runner_->BelongsToCurrentThread()); +} + +void NativeMessagePort::Core::OnMessageFromChrome(const std::string& message) { + DCHECK(message_service_task_runner_->BelongsToCurrentThread()); + host_task_runner_->PostTask(FROM_HERE, + base::Bind(&NativeMessageHost::OnMessage, + base::Unretained(host_.get()), + message)); +} + +void NativeMessagePort::Core::PostMessageFromNativeHost( + const std::string& message) { + DCHECK(host_task_runner_->BelongsToCurrentThread()); + message_service_task_runner_->PostTask( + FROM_HERE, + base::Bind( + &NativeMessagePort::PostMessageFromNativeHost, port_, message)); +} + +void NativeMessagePort::Core::CloseChannel(const std::string& error_message) { + DCHECK(host_task_runner_->BelongsToCurrentThread()); + message_service_task_runner_->PostTask( + FROM_HERE, + base::Bind(&NativeMessagePort::CloseChannel, port_, error_message)); +} + +NativeMessagePort::NativeMessagePort( + base::WeakPtr<MessageService> message_service, + int port_id, + scoped_ptr<NativeMessageHost> native_message_host) + : weak_message_service_(message_service), + host_task_runner_(native_message_host->task_runner()), + port_id_(port_id), + weak_factory_(this) { + core_.reset(new Core(native_message_host.Pass(), + weak_factory_.GetWeakPtr(), + base::MessageLoopProxy::current())); } NativeMessagePort::~NativeMessagePort() { - content::BrowserThread::DeleteSoon( - content::BrowserThread::IO, FROM_HERE, native_process_); + DCHECK(thread_checker_.CalledOnValidThread()); + host_task_runner_->DeleteSoon(FROM_HERE, core_.release()); } void NativeMessagePort::DispatchOnMessage( const Message& message, int target_port_id) { - content::BrowserThread::PostTask( - content::BrowserThread::IO, FROM_HERE, - base::Bind(&NativeMessageProcessHost::Send, - base::Unretained(native_process_), message.data)); + DCHECK(thread_checker_.CalledOnValidThread()); + core_->OnMessageFromChrome(message.data); +} + +void NativeMessagePort::PostMessageFromNativeHost(const std::string& message) { + DCHECK(thread_checker_.CalledOnValidThread()); + if (weak_message_service_) { + weak_message_service_->PostMessage( + port_id_, Message(message, false /* user_gesture */)); + } +} + +void NativeMessagePort::CloseChannel(const std::string& error_message) { + DCHECK(thread_checker_.CalledOnValidThread()); + if (weak_message_service_) { + weak_message_service_->CloseChannel(port_id_, error_message); + } } } // namespace extensions |