1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
// Copyright (c) 2012 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 "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 {
// 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_);
~Core() override;
void OnMessageFromChrome(const std::string& message);
// NativeMessageHost::Client implementation.
void PostMessageFromNativeHost(const std::string& message) override;
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() {
DCHECK(thread_checker_.CalledOnValidThread());
host_task_runner_->DeleteSoon(FROM_HERE, core_.release());
}
void NativeMessagePort::DispatchOnMessage(
const Message& message,
int target_port_id) {
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
|