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 125 126 127 128 129 130 131 132 133
|
// 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 <utility>
#include "base/bind.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chrome/browser/extensions/api/messaging/native_message_process_host.h"
#include "content/public/browser/browser_thread.h"
#include "extensions/common/api/messaging/message.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(
std::unique_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:
std::unique_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(
std::unique_ptr<NativeMessageHost> host,
base::WeakPtr<NativeMessagePort> port,
scoped_refptr<base::SingleThreadTaskRunner> message_service_task_runner)
: host_(std::move(host)),
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::BindOnce(&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::BindOnce(&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::BindOnce(&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::BindOnce(&NativeMessagePort::CloseChannel, port_, error_message));
}
NativeMessagePort::NativeMessagePort(
base::WeakPtr<ChannelDelegate> channel_delegate,
const PortId& port_id,
std::unique_ptr<NativeMessageHost> native_message_host)
: weak_channel_delegate_(channel_delegate),
host_task_runner_(native_message_host->task_runner()),
port_id_(port_id),
weak_factory_(this) {
core_.reset(new Core(std::move(native_message_host),
weak_factory_.GetWeakPtr(),
base::ThreadTaskRunnerHandle::Get()));
}
NativeMessagePort::~NativeMessagePort() {
DCHECK(thread_checker_.CalledOnValidThread());
host_task_runner_->DeleteSoon(FROM_HERE, core_.release());
}
bool NativeMessagePort::IsValidPort() {
// The native message port is immediately connected after construction, so it
// is not possible to invalidate the port between construction and connection.
// The return value doesn't matter since native messaging follows a code path
// where IsValidPort() is never called.
NOTREACHED();
return true;
}
void NativeMessagePort::DispatchOnMessage(const Message& message) {
DCHECK(thread_checker_.CalledOnValidThread());
core_->OnMessageFromChrome(message.data);
}
void NativeMessagePort::PostMessageFromNativeHost(const std::string& message) {
DCHECK(thread_checker_.CalledOnValidThread());
if (weak_channel_delegate_) {
weak_channel_delegate_->PostMessage(
port_id_, Message(message, false /* user_gesture */));
}
}
void NativeMessagePort::CloseChannel(const std::string& error_message) {
DCHECK(thread_checker_.CalledOnValidThread());
if (weak_channel_delegate_) {
weak_channel_delegate_->CloseChannel(port_id_, error_message);
}
}
} // namespace extensions
|