diff options
author | kelvinp <kelvinp@chromium.org> | 2014-10-06 21:17:53 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-10-07 04:18:26 +0000 |
commit | ba722a2a8ddf967dcadb483ea32d5ad31fc4bdf6 (patch) | |
tree | dad735bc048ba6aae7b7a68752c397ac4109c4c5 /remoting | |
parent | 64fe322511ff993244186c54ff734fee8036ad4f (diff) | |
download | chromium_src-ba722a2a8ddf967dcadb483ea32d5ad31fc4bdf6.zip chromium_src-ba722a2a8ddf967dcadb483ea32d5ad31fc4bdf6.tar.gz chromium_src-ba722a2a8ddf967dcadb483ea32d5ad31fc4bdf6.tar.bz2 |
Remote Assistance on Chrome OS Part III - NativeMessageHost
This CL extracts the NativeMessageHost interface from the NativeMessageProcessHost
A NativeMessageHost hosts a native component, which can be
running in the same process as chrome or in a separate
process.
Review URL: https://codereview.chromium.org/591463003
Cr-Commit-Position: refs/heads/master@{#298366}
Diffstat (limited to 'remoting')
8 files changed, 185 insertions, 69 deletions
diff --git a/remoting/host/it2me/com.google.chrome.remote_assistance.json.jinja2 b/remoting/host/it2me/com.google.chrome.remote_assistance.json.jinja2 index 9c90357..5545dc8 100644 --- a/remoting/host/it2me/com.google.chrome.remote_assistance.json.jinja2 +++ b/remoting/host/it2me/com.google.chrome.remote_assistance.json.jinja2 @@ -3,6 +3,9 @@ "description": "{{ IT2ME_HOST_DESCRIPTION }}", "type": "stdio", "path": "{{ IT2ME_HOST_PATH }}", + // If you modify the list of allowed_origins, don't forget to update + // chrome/browser/extensions/messaging/native_message_host_chromeos.cc + // to keep the two lists in sync. "allowed_origins": [ "chrome-extension://ljacajndfccfgnfohlgkdphmbnpkjflk/", "chrome-extension://gbchcmhmhahfdphkhkmpfmihenigjmpp/", diff --git a/remoting/host/it2me/it2me_native_messaging_host.cc b/remoting/host/it2me/it2me_native_messaging_host.cc index 8d0d131..24ddc1b 100644 --- a/remoting/host/it2me/it2me_native_messaging_host.cc +++ b/remoting/host/it2me/it2me_native_messaging_host.cc @@ -9,9 +9,8 @@ #include "base/basictypes.h" #include "base/bind.h" #include "base/callback.h" -#include "base/callback_helpers.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" +#include "base/json/json_reader.h" +#include "base/json/json_writer.h" #include "base/strings/string_number_conversions.h" #include "base/strings/stringize_macros.h" #include "base/threading/thread.h" @@ -42,9 +41,8 @@ const remoting::protocol::NameMapElement<It2MeHostState> kIt2MeHostStates[] = { It2MeNativeMessagingHost::It2MeNativeMessagingHost( scoped_refptr<AutoThreadTaskRunner> task_runner, - scoped_ptr<extensions::NativeMessagingChannel> channel, scoped_ptr<It2MeHostFactory> factory) - : channel_(channel.Pass()), + : client_(NULL), factory_(factory.Pass()), weak_factory_(this) { weak_ptr_ = weak_factory_.GetWeakPtr(); @@ -75,27 +73,19 @@ It2MeNativeMessagingHost::~It2MeNativeMessagingHost() { } } -void It2MeNativeMessagingHost::Start(const base::Closure& quit_closure) { +void It2MeNativeMessagingHost::OnMessage(const std::string& message) { DCHECK(task_runner()->BelongsToCurrentThread()); - DCHECK(!quit_closure.is_null()); - quit_closure_ = quit_closure; - - channel_->Start(this); -} - -void It2MeNativeMessagingHost::OnMessage(scoped_ptr<base::Value> message) { - DCHECK(task_runner()->BelongsToCurrentThread()); - - if (!message->IsType(base::Value::TYPE_DICTIONARY)) { + scoped_ptr<base::DictionaryValue> response(new base::DictionaryValue()); + scoped_ptr<base::Value> message_value(base::JSONReader::Read(message)); + if (!message_value->IsType(base::Value::TYPE_DICTIONARY)) { LOG(ERROR) << "Received a message that's not a dictionary."; - channel_->SendMessage(nullptr); + client_->CloseChannel(std::string()); return; } scoped_ptr<base::DictionaryValue> message_dict( - static_cast<base::DictionaryValue*>(message.release())); - scoped_ptr<base::DictionaryValue> response(new base::DictionaryValue()); + static_cast<base::DictionaryValue*>(message_value.release())); // If the client supplies an ID, it will expect it in the response. This // might be a string or a number, so cope with both. @@ -122,9 +112,17 @@ void It2MeNativeMessagingHost::OnMessage(scoped_ptr<base::Value> message) { } } -void It2MeNativeMessagingHost::OnDisconnect() { - if (!quit_closure_.is_null()) - base::ResetAndReturn(&quit_closure_).Run(); +void It2MeNativeMessagingHost::Start(Client* client) { + DCHECK(task_runner()->BelongsToCurrentThread()); + client_ = client; +} + +void It2MeNativeMessagingHost::SendMessageToClient( + scoped_ptr<base::DictionaryValue> message) const { + DCHECK(task_runner()->BelongsToCurrentThread()); + std::string message_json; + base::JSONWriter::Write(message.get(), &message_json); + client_->PostMessageFromNativeHost(message_json); } void It2MeNativeMessagingHost::ProcessHello( @@ -138,7 +136,7 @@ void It2MeNativeMessagingHost::ProcessHello( scoped_ptr<base::ListValue> supported_features_list(new base::ListValue()); response->Set("supportedFeatures", supported_features_list.release()); - channel_->SendMessage(response.Pass()); + SendMessageToClient(response.Pass()); } void It2MeNativeMessagingHost::ProcessConnect( @@ -212,7 +210,7 @@ void It2MeNativeMessagingHost::ProcessConnect( directory_bot_jid_); it2me_host_->Connect(); - channel_->SendMessage(response.Pass()); + SendMessageToClient(response.Pass()); } void It2MeNativeMessagingHost::ProcessDisconnect( @@ -224,7 +222,7 @@ void It2MeNativeMessagingHost::ProcessDisconnect( it2me_host_->Disconnect(); it2me_host_ = NULL; } - channel_->SendMessage(response.Pass()); + SendMessageToClient(response.Pass()); } void It2MeNativeMessagingHost::SendErrorAndExit( @@ -236,10 +234,10 @@ void It2MeNativeMessagingHost::SendErrorAndExit( response->SetString("type", "error"); response->SetString("description", description); - channel_->SendMessage(response.Pass()); + SendMessageToClient(response.Pass()); - // Trigger a host shutdown by sending a NULL message. - channel_->SendMessage(nullptr); + // Trigger a host shutdown by sending an empty message. + client_->CloseChannel(std::string()); } void It2MeNativeMessagingHost::OnStateChanged(It2MeHostState state) { @@ -272,7 +270,7 @@ void It2MeNativeMessagingHost::OnStateChanged(It2MeHostState state) { ; } - channel_->SendMessage(message.Pass()); + SendMessageToClient(message.Pass()); } void It2MeNativeMessagingHost::OnNatPolicyChanged(bool nat_traversal_enabled) { @@ -282,7 +280,7 @@ void It2MeNativeMessagingHost::OnNatPolicyChanged(bool nat_traversal_enabled) { message->SetString("type", "natPolicyChanged"); message->SetBoolean("natTraversalEnabled", nat_traversal_enabled); - channel_->SendMessage(message.Pass()); + SendMessageToClient(message.Pass()); } // Stores the Access Code for the web-app to query. @@ -303,7 +301,7 @@ void It2MeNativeMessagingHost::OnClientAuthenticated( client_username_ = client_username; } -scoped_refptr<AutoThreadTaskRunner> +scoped_refptr<base::SingleThreadTaskRunner> It2MeNativeMessagingHost::task_runner() const { return host_context_->ui_task_runner(); } diff --git a/remoting/host/it2me/it2me_native_messaging_host.h b/remoting/host/it2me/it2me_native_messaging_host.h index f9d8ac9..18e738b 100644 --- a/remoting/host/it2me/it2me_native_messaging_host.h +++ b/remoting/host/it2me/it2me_native_messaging_host.h @@ -8,40 +8,38 @@ #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" -#include "extensions/browser/api/messaging/native_messaging_channel.h" +#include "extensions/browser/api/messaging/native_message_host.h" #include "remoting/base/auto_thread_task_runner.h" #include "remoting/host/it2me/it2me_host.h" namespace base { class DictionaryValue; +class Value; } // namespace base namespace remoting { // Implementation of the native messaging host process. -class It2MeNativeMessagingHost - : public It2MeHost::Observer, - public extensions::NativeMessagingChannel::EventHandler { +class It2MeNativeMessagingHost : public It2MeHost::Observer, + public extensions::NativeMessageHost { public: - It2MeNativeMessagingHost( - scoped_refptr<AutoThreadTaskRunner> task_runner, - scoped_ptr<extensions::NativeMessagingChannel> channel, - scoped_ptr<It2MeHostFactory> factory); + It2MeNativeMessagingHost(scoped_refptr<AutoThreadTaskRunner> task_runner, + scoped_ptr<It2MeHostFactory> factory); virtual ~It2MeNativeMessagingHost(); - void Start(const base::Closure& quit_closure); - - // extensions::NativeMessagingChannel::EventHandler implementation. - virtual void OnMessage(scoped_ptr<base::Value> message) OVERRIDE; - virtual void OnDisconnect() OVERRIDE; + // extensions::NativeMessageHost implementation. + virtual void OnMessage(const std::string& message) override; + virtual void Start(Client* client) override; + virtual scoped_refptr<base::SingleThreadTaskRunner> task_runner() + const override; // It2MeHost::Observer implementation. virtual void OnClientAuthenticated(const std::string& client_username) - OVERRIDE; + override; virtual void OnStoreAccessCode(const std::string& access_code, - base::TimeDelta access_code_lifetime) OVERRIDE; - virtual void OnNatPolicyChanged(bool nat_traversal_enabled) OVERRIDE; - virtual void OnStateChanged(It2MeHostState state) OVERRIDE; + base::TimeDelta access_code_lifetime) override; + virtual void OnNatPolicyChanged(bool nat_traversal_enabled) override; + virtual void OnStateChanged(It2MeHostState state) override; static std::string HostStateToString(It2MeHostState host_state); @@ -57,12 +55,9 @@ class It2MeNativeMessagingHost scoped_ptr<base::DictionaryValue> response); void SendErrorAndExit(scoped_ptr<base::DictionaryValue> response, const std::string& description) const; + void SendMessageToClient(scoped_ptr<base::DictionaryValue> message) const; - base::Closure quit_closure_; - - scoped_refptr<AutoThreadTaskRunner> task_runner() const; - - scoped_ptr<extensions::NativeMessagingChannel> channel_; + Client* client_; scoped_ptr<It2MeHostFactory> factory_; scoped_ptr<ChromotingHostContext> host_context_; scoped_refptr<It2MeHost> it2me_host_; diff --git a/remoting/host/it2me/it2me_native_messaging_host_main.cc b/remoting/host/it2me/it2me_native_messaging_host_main.cc index 25f5021..7d27d19 100644 --- a/remoting/host/it2me/it2me_native_messaging_host_main.cc +++ b/remoting/host/it2me/it2me_native_messaging_host_main.cc @@ -16,6 +16,7 @@ #include "remoting/host/host_exit_codes.h" #include "remoting/host/it2me/it2me_native_messaging_host.h" #include "remoting/host/logging.h" +#include "remoting/host/native_messaging/native_messaging_pipe.h" #include "remoting/host/native_messaging/pipe_messaging_channel.h" #include "remoting/host/usage_stats_consent.h" @@ -117,13 +118,21 @@ int StartIt2MeNativeMessagingHost() { scoped_ptr<It2MeHostFactory> factory(new It2MeHostFactory()); + scoped_ptr<NativeMessagingPipe> native_messaging_pipe( + new NativeMessagingPipe()); + // Set up the native messaging channel. scoped_ptr<extensions::NativeMessagingChannel> channel( new PipeMessagingChannel(read_file.Pass(), write_file.Pass())); - scoped_ptr<It2MeNativeMessagingHost> host(new It2MeNativeMessagingHost( - task_runner, channel.Pass(), factory.Pass())); - host->Start(run_loop.QuitClosure()); + scoped_ptr<extensions::NativeMessageHost> host(new It2MeNativeMessagingHost( + task_runner, + factory.Pass())); + + host->Start(native_messaging_pipe.get()); + + native_messaging_pipe->Start( + host.Pass(), channel.Pass(), run_loop.QuitClosure()); // Run the loop until channel is alive. run_loop.Run(); diff --git a/remoting/host/it2me/it2me_native_messaging_host_unittest.cc b/remoting/host/it2me/it2me_native_messaging_host_unittest.cc index 56515a9..61334cf 100644 --- a/remoting/host/it2me/it2me_native_messaging_host_unittest.cc +++ b/remoting/host/it2me/it2me_native_messaging_host_unittest.cc @@ -17,6 +17,7 @@ #include "net/base/net_util.h" #include "remoting/base/auto_thread_task_runner.h" #include "remoting/host/chromoting_host_context.h" +#include "remoting/host/native_messaging/native_messaging_pipe.h" #include "remoting/host/native_messaging/pipe_messaging_channel.h" #include "remoting/host/setup/test_util.h" #include "testing/gtest/include/gtest/gtest.h" @@ -78,9 +79,9 @@ class MockIt2MeHost : public It2MeHost { directory_bot_jid) {} // It2MeHost overrides - virtual void Connect() OVERRIDE; - virtual void Disconnect() OVERRIDE; - virtual void RequestNatPolicy() OVERRIDE; + virtual void Connect() override; + virtual void Disconnect() override; + virtual void RequestNatPolicy() override; private: virtual ~MockIt2MeHost() {} @@ -153,7 +154,7 @@ class MockIt2MeHostFactory : public It2MeHostFactory { scoped_refptr<base::SingleThreadTaskRunner> task_runner, base::WeakPtr<It2MeHost::Observer> observer, const XmppSignalStrategy::XmppServerConfig& xmpp_server_config, - const std::string& directory_bot_jid) OVERRIDE { + const std::string& directory_bot_jid) override { return new MockIt2MeHost( context, task_runner, observer, xmpp_server_config, directory_bot_jid); } @@ -167,8 +168,8 @@ class It2MeNativeMessagingHostTest : public testing::Test { It2MeNativeMessagingHostTest() {} virtual ~It2MeNativeMessagingHostTest() {} - virtual void SetUp() OVERRIDE; - virtual void TearDown() OVERRIDE; + virtual void SetUp() override; + virtual void TearDown() override; protected: scoped_ptr<base::DictionaryValue> ReadMessageFromOutputPipe(); @@ -209,7 +210,7 @@ class It2MeNativeMessagingHostTest : public testing::Test { // Task runner of the host thread. scoped_refptr<AutoThreadTaskRunner> host_task_runner_; - scoped_ptr<remoting::It2MeNativeMessagingHost> host_; + scoped_ptr<remoting::NativeMessagingPipe> pipe_; DISALLOW_COPY_AND_ASSIGN(It2MeNativeMessagingHostTest); }; @@ -431,15 +432,21 @@ void It2MeNativeMessagingHostTest::StartHost() { // Creating a native messaging host with a mock It2MeHostFactory. scoped_ptr<It2MeHostFactory> factory(new MockIt2MeHostFactory()); + pipe_.reset(new NativeMessagingPipe()); + scoped_ptr<extensions::NativeMessagingChannel> channel( new PipeMessagingChannel(input_read_file.Pass(), output_write_file.Pass())); - host_.reset(new It2MeNativeMessagingHost( - host_task_runner_, - channel.Pass(), - factory.Pass())); - host_->Start(base::Bind(&It2MeNativeMessagingHostTest::StopHost, + scoped_ptr<extensions::NativeMessageHost> it2me_host( + new It2MeNativeMessagingHost( + host_task_runner_, + factory.Pass())); + it2me_host->Start(pipe_.get()); + + pipe_->Start(it2me_host.Pass(), + channel.Pass(), + base::Bind(&It2MeNativeMessagingHostTest::StopHost, base::Unretained(this))); // Notify the test that the host has finished starting up. @@ -450,7 +457,7 @@ void It2MeNativeMessagingHostTest::StartHost() { void It2MeNativeMessagingHostTest::StopHost() { DCHECK(host_task_runner_->RunsTasksOnCurrentThread()); - host_.reset(); + pipe_.reset(); // Wait till all shutdown tasks have completed. base::RunLoop().RunUntilIdle(); diff --git a/remoting/host/native_messaging/native_messaging_pipe.cc b/remoting/host/native_messaging/native_messaging_pipe.cc new file mode 100644 index 0000000..13abc35 --- /dev/null +++ b/remoting/host/native_messaging/native_messaging_pipe.cc @@ -0,0 +1,52 @@ +// 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 "remoting/host/native_messaging/native_messaging_pipe.h" + +#include "base/callback_helpers.h" +#include "base/json/json_reader.h" +#include "base/json/json_writer.h" +#include "base/values.h" + +namespace remoting { + +NativeMessagingPipe::NativeMessagingPipe() { +} + +NativeMessagingPipe::~NativeMessagingPipe() { +} + +void NativeMessagingPipe::Start( + scoped_ptr<extensions::NativeMessageHost> host, + scoped_ptr<extensions::NativeMessagingChannel> channel, + const base::Closure& quit_closure) { + host_ = host.Pass(); + channel_ = channel.Pass(); + quit_closure_ = quit_closure; + channel_->Start(this); +} + +void NativeMessagingPipe::OnMessage(scoped_ptr<base::Value> message) { + std::string message_json; + base::JSONWriter::Write(message.get(), &message_json); + host_->OnMessage(message_json); +} + +void NativeMessagingPipe::OnDisconnect() { + if (!quit_closure_.is_null()) + base::ResetAndReturn(&quit_closure_).Run(); +} + +void NativeMessagingPipe::PostMessageFromNativeHost( + const std::string& message) { + scoped_ptr<base::Value> json(base::JSONReader::Read(message)); + channel_->SendMessage(json.Pass()); +} + +void NativeMessagingPipe::CloseChannel(const std::string& error_message) { + if (!quit_closure_.is_null()) + base::ResetAndReturn(&quit_closure_).Run(); +} + +} // namespace remoting diff --git a/remoting/host/native_messaging/native_messaging_pipe.h b/remoting/host/native_messaging/native_messaging_pipe.h new file mode 100644 index 0000000..24a16f7 --- /dev/null +++ b/remoting/host/native_messaging/native_messaging_pipe.h @@ -0,0 +1,50 @@ +// 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 REMOTING_HOST_NATIVE_MESSAGING_NATIVE_MESSAGING_PIPE_H_ +#define REMOTING_HOST_NATIVE_MESSAGING_NATIVE_MESSAGING_PIPE_H_ + +#include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" +#include "extensions/browser/api/messaging/native_message_host.h" +#include "extensions/browser/api/messaging/native_messaging_channel.h" + +namespace base { +class Value; +} + +namespace remoting { + +// Connects a extensions::NativeMessageHost to a PipeMessagingChannel. +class NativeMessagingPipe + : public extensions::NativeMessagingChannel::EventHandler, + public extensions::NativeMessageHost::Client { + public: + NativeMessagingPipe(); + virtual ~NativeMessagingPipe(); + + // Starts processing messages from the pipe. + void Start(scoped_ptr<extensions::NativeMessageHost> host, + scoped_ptr<extensions::NativeMessagingChannel> channel, + const base::Closure& quit_closure); + + // extensions::NativeMessageHost::Client implementation. + virtual void PostMessageFromNativeHost(const std::string& message) override; + virtual void CloseChannel(const std::string& error_message) override; + + // extensions::NativeMessagingChannel::EventHandler implementation. + virtual void OnMessage(scoped_ptr<base::Value> message) override; + virtual void OnDisconnect() override; + + private: + base::Closure quit_closure_; + scoped_ptr<extensions::NativeMessagingChannel> channel_; + scoped_ptr<extensions::NativeMessageHost> host_; + + DISALLOW_COPY_AND_ASSIGN(NativeMessagingPipe); +}; + +} // namespace remoting + +#endif // REMOTING_HOST_NATIVE_MESSAGING_NATIVE_MESSAGING_PIPE_H_ diff --git a/remoting/remoting_host.gypi b/remoting/remoting_host.gypi index eca5646..5538700 100644 --- a/remoting/remoting_host.gypi +++ b/remoting/remoting_host.gypi @@ -431,6 +431,8 @@ 'sources': [ 'host/native_messaging/pipe_messaging_channel.cc', 'host/native_messaging/pipe_messaging_channel.h', + 'host/native_messaging/native_messaging_pipe.cc', + 'host/native_messaging/native_messaging_pipe.h', 'host/native_messaging/native_messaging_reader.cc', 'host/native_messaging/native_messaging_reader.h', 'host/native_messaging/native_messaging_writer.cc', |