Index: chrome/browser/extensions/api/messaging/native_message_port.cc |
diff --git a/chrome/browser/extensions/api/messaging/native_message_port.cc b/chrome/browser/extensions/api/messaging/native_message_port.cc |
index a0a47d561bbb77cad1e495fcaad3a1a5bb46da41..66b1674e2e45dcd36a0dc0a4cbe08389fbf26736 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 |