diff options
Diffstat (limited to 'remoting')
-rw-r--r-- | remoting/host/chromoting_host.cc | 24 | ||||
-rw-r--r-- | remoting/host/chromoting_host.h | 12 | ||||
-rw-r--r-- | remoting/host/client_session.cc | 32 | ||||
-rw-r--r-- | remoting/host/client_session.h | 22 | ||||
-rw-r--r-- | remoting/host/client_session_unittest.cc | 201 | ||||
-rw-r--r-- | remoting/host/host_extension.h | 40 | ||||
-rw-r--r-- | remoting/host/host_extension_session.h | 33 | ||||
-rw-r--r-- | remoting/host/host_mock_objects.h | 1 | ||||
-rw-r--r-- | remoting/protocol/session_config.cc | 2 | ||||
-rw-r--r-- | remoting/remoting_host.gypi | 2 |
10 files changed, 365 insertions, 4 deletions
diff --git a/remoting/host/chromoting_host.cc b/remoting/host/chromoting_host.cc index ef2ea19..942e643 100644 --- a/remoting/host/chromoting_host.cc +++ b/remoting/host/chromoting_host.cc @@ -141,6 +141,10 @@ void ChromotingHost::RemoveStatusObserver(HostStatusObserver* observer) { status_observers_.RemoveObserver(observer); } +void ChromotingHost::AddExtension(scoped_ptr<HostExtension> extension) { + extensions_.push_back(extension.release()); +} + void ChromotingHost::RejectAuthenticatingClient() { DCHECK(authenticating_client_); reject_authenticating_client_ = true; @@ -230,6 +234,19 @@ void ChromotingHost::OnSessionChannelsConnected(ClientSession* client) { OnClientConnected(client->client_jid())); } +void ChromotingHost::OnSessionClientCapabilities(ClientSession* client) { + DCHECK(CalledOnValidThread()); + + // Create extension sessions from each registered extension for this client. + for (HostExtensionList::iterator extension = extensions_.begin(); + extension != extensions_.end(); ++extension) { + scoped_ptr<HostExtensionSession> extension_session = + (*extension)->CreateExtensionSession(client); + if (extension_session) + client->AddExtensionSession(extension_session.Pass()); + } +} + void ChromotingHost::OnSessionAuthenticationFailed(ClientSession* client) { DCHECK(CalledOnValidThread()); @@ -320,6 +337,13 @@ void ChromotingHost::OnIncomingSession( desktop_environment_factory_, max_session_duration_, pairing_registry_); + + // Registers capabilities provided by host extensions. + for (HostExtensionList::iterator extension = extensions_.begin(); + extension != extensions_.end(); ++extension) { + client->AddHostCapabilities((*extension)->GetCapabilities()); + } + clients_.push_back(client); } diff --git a/remoting/host/chromoting_host.h b/remoting/host/chromoting_host.h index a6642d4..73e8442 100644 --- a/remoting/host/chromoting_host.h +++ b/remoting/host/chromoting_host.h @@ -8,14 +8,16 @@ #include <list> #include <string> -#include "base/memory/scoped_ptr.h" #include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/scoped_vector.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "base/threading/non_thread_safe.h" #include "base/threading/thread.h" #include "net/base/backoff_entry.h" #include "remoting/host/client_session.h" +#include "remoting/host/host_extension.h" #include "remoting/host/host_status_monitor.h" #include "remoting/host/host_status_observer.h" #include "remoting/protocol/authenticator.h" @@ -91,6 +93,9 @@ class ChromotingHost : public base::NonThreadSafe, virtual void AddStatusObserver(HostStatusObserver* observer) OVERRIDE; virtual void RemoveStatusObserver(HostStatusObserver* observer) OVERRIDE; + // Registers a host extension. + void AddExtension(scoped_ptr<HostExtension> extension); + // This method may be called only from // HostStatusObserver::OnClientAuthenticated() to reject the new // client. @@ -118,6 +123,7 @@ class ChromotingHost : public base::NonThreadSafe, virtual void OnSessionAuthenticating(ClientSession* client) OVERRIDE; virtual bool OnSessionAuthenticated(ClientSession* client) OVERRIDE; virtual void OnSessionChannelsConnected(ClientSession* client) OVERRIDE; + virtual void OnSessionClientCapabilities(ClientSession* client) OVERRIDE; virtual void OnSessionAuthenticationFailed(ClientSession* client) OVERRIDE; virtual void OnSessionClosed(ClientSession* session) OVERRIDE; virtual void OnSessionSequenceNumber(ClientSession* session, @@ -154,6 +160,7 @@ class ChromotingHost : public base::NonThreadSafe, friend class ChromotingHostTest; typedef std::list<ClientSession*> ClientList; + typedef ScopedVector<HostExtension> HostExtensionList; // Immediately disconnects all active clients. Host-internal components may // shutdown asynchronously, but the caller is guaranteed not to receive @@ -204,6 +211,9 @@ class ChromotingHost : public base::NonThreadSafe, // The pairing registry for PIN-less authentication. scoped_refptr<protocol::PairingRegistry> pairing_registry_; + // List of host extensions. + HostExtensionList extensions_; + base::WeakPtrFactory<ChromotingHost> weak_factory_; DISALLOW_COPY_AND_ASSIGN(ChromotingHost); diff --git a/remoting/host/client_session.cc b/remoting/host/client_session.cc index fd1e441..0361932 100644 --- a/remoting/host/client_session.cc +++ b/remoting/host/client_session.cc @@ -18,6 +18,7 @@ #include "remoting/host/audio_capturer.h" #include "remoting/host/audio_scheduler.h" #include "remoting/host/desktop_environment.h" +#include "remoting/host/host_extension_session.h" #include "remoting/host/input_injector.h" #include "remoting/host/screen_controls.h" #include "remoting/host/screen_resolution.h" @@ -98,6 +99,25 @@ ClientSession::~ClientSession() { connection_.reset(); } +void ClientSession::AddExtensionSession( + scoped_ptr<HostExtensionSession> extension_session) { + DCHECK(CalledOnValidThread()); + + extension_sessions_.push_back(extension_session.release()); +} + +void ClientSession::AddHostCapabilities(const std::string& capabilities) { + DCHECK(CalledOnValidThread()); + + if (capabilities.empty()) + return; + + if (!host_capabilities_.empty()) + host_capabilities_.append(" "); + + host_capabilities_.append(capabilities); +} + void ClientSession::NotifyClientResolution( const protocol::ClientResolution& resolution) { DCHECK(CalledOnValidThread()); @@ -168,6 +188,7 @@ void ClientSession::SetCapabilities( *client_capabilities_ = capabilities.capabilities(); VLOG(1) << "Client capabilities: " << *client_capabilities_; + event_handler_->OnSessionClientCapabilities(this); // Calculate the set of capabilities enabled by both client and host and // pass it to the desktop environment if it is available. @@ -204,6 +225,13 @@ void ClientSession::DeliverClientMessage( HOST_LOG << "gnubby auth is not enabled"; } return; + } else { + for(HostExtensionSessionList::iterator it = extension_sessions_.begin(); + it != extension_sessions_.end(); ++it) { + // Extension returns |true| to indicate that the message was handled. + if ((*it)->OnExtensionMessage(this, message)) + return; + } } } HOST_LOG << "Unexpected message received: " @@ -253,7 +281,7 @@ void ClientSession::OnConnectionAuthenticated( return; } - host_capabilities_ = desktop_environment_->GetCapabilities(); + AddHostCapabilities(desktop_environment_->GetCapabilities()); // Ignore protocol::Capabilities messages from the client if it does not // support any capabilities. @@ -261,6 +289,8 @@ void ClientSession::OnConnectionAuthenticated( VLOG(1) << "The client does not support any capabilities."; client_capabilities_ = make_scoped_ptr(new std::string()); + event_handler_->OnSessionClientCapabilities(this); + desktop_environment_->SetCapabilities(*client_capabilities_); } diff --git a/remoting/host/client_session.h b/remoting/host/client_session.h index f892329..a86839e 100644 --- a/remoting/host/client_session.h +++ b/remoting/host/client_session.h @@ -8,6 +8,7 @@ #include <string> #include "base/memory/ref_counted.h" +#include "base/memory/scoped_vector.h" #include "base/memory/weak_ptr.h" #include "base/sequenced_task_runner_helpers.h" #include "base/threading/non_thread_safe.h" @@ -15,6 +16,8 @@ #include "base/timer/timer.h" #include "remoting/host/client_session_control.h" #include "remoting/host/gnubby_auth_handler.h" +#include "remoting/host/host_extension.h" +#include "remoting/host/host_extension_session.h" #include "remoting/host/mouse_clamping_filter.h" #include "remoting/host/remote_input_filter.h" #include "remoting/protocol/clipboard_echo_filter.h" @@ -64,6 +67,9 @@ class ClientSession // Called after we've finished connecting all channels. virtual void OnSessionChannelsConnected(ClientSession* client) = 0; + // Called after client has reported capabilities. + virtual void OnSessionClientCapabilities(ClientSession* client) = 0; + // Called after authentication has failed. Must not tear down this // object. OnSessionClosed() is notified after this handler // returns. @@ -103,6 +109,13 @@ class ClientSession scoped_refptr<protocol::PairingRegistry> pairing_registry); virtual ~ClientSession(); + // Adds an extension to client to handle extension messages. + void AddExtensionSession(scoped_ptr<HostExtensionSession> extension_session); + + // Adds extended capabilities to advertise to the client, e.g. those + // implemented by |DesktopEnvironment| or |HostExtension|s. + void AddHostCapabilities(const std::string& capability); + // protocol::HostStub interface. virtual void NotifyClientResolution( const protocol::ClientResolution& resolution) OVERRIDE; @@ -148,7 +161,13 @@ class ClientSession bool is_authenticated() { return auth_input_filter_.enabled(); } + const std::string* client_capabilities() const { + return client_capabilities_.get(); + } + private: + typedef ScopedVector<HostExtensionSession> HostExtensionSessionList; + // Creates a proxy for sending clipboard events to the client. scoped_ptr<protocol::ClipboardStub> CreateClipboardProxy(); @@ -244,6 +263,9 @@ class ClientSession // Used to proxy gnubby auth traffic. scoped_ptr<GnubbyAuthHandler> gnubby_auth_handler_; + // Host extension sessions, used to handle extension messages. + HostExtensionSessionList extension_sessions_; + DISALLOW_COPY_AND_ASSIGN(ClientSession); }; diff --git a/remoting/host/client_session_unittest.cc b/remoting/host/client_session_unittest.cc index f28050a..d648ba1 100644 --- a/remoting/host/client_session_unittest.cc +++ b/remoting/host/client_session_unittest.cc @@ -2,17 +2,24 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <algorithm> +#include <string> +#include <vector> + #include "base/message_loop/message_loop.h" +#include "base/strings/string_util.h" #include "base/test/test_simple_task_runner.h" #include "remoting/base/auto_thread_task_runner.h" #include "remoting/base/constants.h" #include "remoting/host/audio_capturer.h" #include "remoting/host/client_session.h" #include "remoting/host/desktop_environment.h" +#include "remoting/host/host_extension.h" #include "remoting/host/host_mock_objects.h" #include "remoting/host/screen_capturer_fake.h" #include "remoting/protocol/protocol_mock_objects.h" #include "testing/gmock/include/gmock/gmock-matchers.h" +#include "testing/gmock_mutant.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h" #include "third_party/webrtc/modules/desktop_capture/desktop_region.h" @@ -31,9 +38,11 @@ using protocol::SessionConfig; using testing::_; using testing::AnyNumber; using testing::AtMost; +using testing::CreateFunctor; using testing::DeleteArg; using testing::DoAll; using testing::Expectation; +using testing::Invoke; using testing::Return; using testing::ReturnRef; using testing::Sequence; @@ -42,6 +51,8 @@ using testing::StrictMock; namespace { +const char kDefaultTestCapability[] = "default"; + ACTION_P2(InjectClipboardEvent, connection, event) { connection->clipboard_stub()->InjectClipboardEvent(event); } @@ -67,8 +78,75 @@ ACTION_P2(DeliverClientMessage, client_session, message) { client_session->DeliverClientMessage(message); } +ACTION_P2(AddHostCapabilities, client_session, capability) { + client_session->AddHostCapabilities(capability); } +// Matches a |protocol::Capabilities| argument against a list of capabilities +// formatted as a space-separated string. +MATCHER_P(EqCapabilities, expected_capabilities, "") { + if (!arg.has_capabilities()) + return false; + + std::vector<std::string> words_args; + std::vector<std::string> words_expected; + Tokenize(arg.capabilities(), " ", &words_args); + Tokenize(expected_capabilities, " ", &words_expected); + std::sort(words_args.begin(), words_args.end()); + std::sort(words_expected.begin(), words_expected.end()); + return words_args == words_expected; +} + +// |HostExtension| implementation that can handle an extension message type and +// provide capabilities. +class FakeExtension : public HostExtension { + public: + FakeExtension(const std::string& message_type, + const std::string& capabilities); + virtual ~FakeExtension(); + + virtual std::string GetCapabilities() OVERRIDE; + virtual scoped_ptr<HostExtensionSession> CreateExtensionSession( + ClientSession* client_session) OVERRIDE; + + bool message_handled() { + return message_handled_; + } + + private: + class FakeExtensionSession : public HostExtensionSession { + public: + FakeExtensionSession(FakeExtension* extension); + virtual ~FakeExtensionSession(); + + virtual bool OnExtensionMessage( + ClientSession* client_session, + const protocol::ExtensionMessage& message) OVERRIDE; + + private: + FakeExtension* extension_; + }; + + std::string message_type_; + std::string capabilities_; + bool message_handled_; +}; + +typedef std::vector<HostExtension*> HostExtensionList; + +void CreateExtensionSessions(const HostExtensionList& extensions, + ClientSession* client_session) { + for (HostExtensionList::const_iterator extension = extensions.begin(); + extension != extensions.end(); ++extension) { + scoped_ptr<HostExtensionSession> extension_session = + (*extension)->CreateExtensionSession(client_session); + if (extension_session) + client_session->AddExtensionSession(extension_session.Pass()); + } +} + +} // namespace + class ClientSessionTest : public testing::Test { public: ClientSessionTest() : client_jid_("user@domain/rest-of-jid") {} @@ -100,6 +178,10 @@ class ClientSessionTest : public testing::Test { // the input pipe line and starts video capturing. void ConnectClientSession(); + // Creates expectations to send an extension message and to disconnect + // afterwards. + void SetSendMessageAndDisconnectExpectation(const std::string& message_type); + // Invoked when the last reference to the AutoThreadTaskRunner has been // released and quits the message loop to finish the test. void QuitMainMessageLoop(); @@ -131,6 +213,41 @@ class ClientSessionTest : public testing::Test { scoped_ptr<MockDesktopEnvironmentFactory> desktop_environment_factory_; }; +FakeExtension::FakeExtension(const std::string& message_type, + const std::string& capabilities) + : message_type_(message_type), + capabilities_(capabilities), + message_handled_(false) { +} + +FakeExtension::~FakeExtension() {} + +std::string FakeExtension::GetCapabilities() { + return capabilities_; +} + +scoped_ptr<HostExtensionSession> FakeExtension::CreateExtensionSession( + ClientSession* client_session) { + return scoped_ptr<HostExtensionSession>(new FakeExtensionSession(this)); +} + +FakeExtension::FakeExtensionSession::FakeExtensionSession( + FakeExtension* extension) + : extension_(extension) { +} + +FakeExtension::FakeExtensionSession::~FakeExtensionSession() {} + +bool FakeExtension::FakeExtensionSession::OnExtensionMessage( + ClientSession* client_session, + const protocol::ExtensionMessage& message) { + if (message.type() == extension_->message_type_) { + extension_->message_handled_ = true; + return true; + } + return false; +} + void ClientSessionTest::SetUp() { // Arrange to run |message_loop_| until no components depend on it. scoped_refptr<AutoThreadTaskRunner> ui_task_runner = new AutoThreadTaskRunner( @@ -180,6 +297,11 @@ void ClientSessionTest::SetUp() { desktop_environment_factory_.get(), base::TimeDelta(), NULL)); + + // By default, client will report the same capabilities as the host. + EXPECT_CALL(client_stub_, SetCapabilities(_)) + .Times(AtMost(1)) + .WillOnce(Invoke(client_session_.get(), &ClientSession::SetCapabilities)); } void ClientSessionTest::TearDown() { @@ -211,7 +333,8 @@ DesktopEnvironment* ClientSessionTest::CreateDesktopEnvironment() { EXPECT_CALL(*desktop_environment, CreateVideoCapturerPtr()) .WillOnce(Invoke(this, &ClientSessionTest::CreateVideoCapturer)); EXPECT_CALL(*desktop_environment, GetCapabilities()) - .Times(AtMost(1)); + .Times(AtMost(1)) + .WillOnce(Return(kDefaultTestCapability)); EXPECT_CALL(*desktop_environment, SetCapabilities(_)) .Times(AtMost(1)); @@ -232,6 +355,23 @@ void ClientSessionTest::ConnectClientSession() { client_session_->OnConnectionChannelsConnected(client_session_->connection()); } +void ClientSessionTest::SetSendMessageAndDisconnectExpectation( + const std::string& message_type) { + protocol::ExtensionMessage message; + message.set_type(message_type); + message.set_data("data"); + + Expectation authenticated = + EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_)) + .WillOnce(Return(true)); + EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_)) + .After(authenticated) + .WillOnce(DoAll( + DeliverClientMessage(client_session_.get(), message), + InvokeWithoutArgs(this, &ClientSessionTest::DisconnectClientSession), + InvokeWithoutArgs(this, &ClientSessionTest::StopClientSession))); +} + void ClientSessionTest::QuitMainMessageLoop() { message_loop_.PostTask(FROM_HERE, base::MessageLoop::QuitClosure()); } @@ -599,4 +739,63 @@ TEST_F(ClientSessionTest, EnableGnubbyAuth) { message_loop_.Run(); } +// Verifies that messages can be handled by extensions. +TEST_F(ClientSessionTest, ExtensionMessages_MessageHandled) { + FakeExtension extension1("ext1", "cap1"); + FakeExtension extension2("ext2", "cap2"); + FakeExtension extension3("ext3", "cap3"); + HostExtensionList extensions; + extensions.push_back(&extension1); + extensions.push_back(&extension2); + extensions.push_back(&extension3); + + EXPECT_CALL(session_event_handler_, OnSessionClientCapabilities(_)) + .WillOnce(Invoke(CreateFunctor(&CreateExtensionSessions, extensions))); + + SetSendMessageAndDisconnectExpectation("ext2"); + ConnectClientSession(); + message_loop_.Run(); + + EXPECT_FALSE(extension1.message_handled()); + EXPECT_TRUE(extension2.message_handled()); + EXPECT_FALSE(extension3.message_handled()); +} + +// Verifies that extension messages not handled by extensions don't result in a +// crash. +TEST_F(ClientSessionTest, ExtensionMessages_MessageNotHandled) { + FakeExtension extension1("ext1", "cap1"); + HostExtensionList extensions; + extensions.push_back(&extension1); + + EXPECT_CALL(session_event_handler_, OnSessionClientCapabilities(_)) + .WillOnce(Invoke(CreateFunctor(&CreateExtensionSessions, extensions))); + + SetSendMessageAndDisconnectExpectation("extX"); + ConnectClientSession(); + message_loop_.Run(); + + EXPECT_FALSE(extension1.message_handled()); +} + +TEST_F(ClientSessionTest, ReportCapabilities) { + Expectation authenticated = + EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_)) + .WillOnce(DoAll( + AddHostCapabilities(client_session_.get(), "capX capZ"), + AddHostCapabilities(client_session_.get(), ""), + AddHostCapabilities(client_session_.get(), "capY"), + Return(true))); + EXPECT_CALL(client_stub_, + SetCapabilities(EqCapabilities("capX capY capZ default"))); + EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_)) + .After(authenticated) + .WillOnce(DoAll( + InvokeWithoutArgs(this, &ClientSessionTest::DisconnectClientSession), + InvokeWithoutArgs(this, &ClientSessionTest::StopClientSession))); + + ConnectClientSession(); + message_loop_.Run(); +} + } // namespace remoting diff --git a/remoting/host/host_extension.h b/remoting/host/host_extension.h new file mode 100644 index 0000000..6014f61 --- /dev/null +++ b/remoting/host/host_extension.h @@ -0,0 +1,40 @@ +// 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_HOST_EXTENSION_H_ +#define REMOTING_HOST_HOST_EXTENSION_H_ + +#include <string> + +#include "base/memory/scoped_ptr.h" + +namespace remoting { + +class ClientSession; +class HostExtensionSession; + +// Extends |ChromotingHost| with new functionality, and can use extension +// messages to communicate with the client. +class HostExtension { + public: + virtual ~HostExtension() {} + + // Returns a space-separated list of capabilities provided by this extension. + // Capabilities may be used to inform the client of the availability of an + // extension. They are merged into the capabilities the host reports to the + // client. + virtual std::string GetCapabilities() = 0; + + // Creates an extension session, which can handle extension messages for a + // client session. + // NULL may be returned if |client_session| cannot support this + // extension. + // |client_session| must outlive the resulting |HostExtensionSession|. + virtual scoped_ptr<HostExtensionSession> CreateExtensionSession( + ClientSession* client_session) = 0; +}; + +} // namespace remoting + +#endif // REMOTING_HOST_HOST_EXTENSION_H_ diff --git a/remoting/host/host_extension_session.h b/remoting/host/host_extension_session.h new file mode 100644 index 0000000..54b9c53 --- /dev/null +++ b/remoting/host/host_extension_session.h @@ -0,0 +1,33 @@ +// 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_HOST_EXTENSION_SESSION_H_ +#define REMOTING_HOST_HOST_EXTENSION_SESSION_H_ + +namespace remoting { + +namespace protocol { +class ExtensionMessage; +} // namespace protocol + +class ClientSession; + +// Created by an |HostExtension| to store |ClientSession| specific state, and to +// handle extension messages. +class HostExtensionSession { + public: + virtual ~HostExtensionSession() {} + + // Called when the host receives an |ExtensionMessage| for the |ClientSession| + // associated with this |HostExtensionSession|. + // It returns |true| if the message was handled, and |false| otherwise. + virtual bool OnExtensionMessage( + ClientSession* client_session, + const protocol::ExtensionMessage& message) = 0; +}; + +} // namespace remoting + +#endif // REMOTING_HOST_HOST_EXTENSION_SESSION_H_ + diff --git a/remoting/host/host_mock_objects.h b/remoting/host/host_mock_objects.h index d916f04..383f474 100644 --- a/remoting/host/host_mock_objects.h +++ b/remoting/host/host_mock_objects.h @@ -71,6 +71,7 @@ class MockClientSessionEventHandler : public ClientSession::EventHandler { MOCK_METHOD1(OnSessionAuthenticating, void(ClientSession* client)); MOCK_METHOD1(OnSessionAuthenticated, bool(ClientSession* client)); MOCK_METHOD1(OnSessionChannelsConnected, void(ClientSession* client)); + MOCK_METHOD1(OnSessionClientCapabilities, void(ClientSession* client)); MOCK_METHOD1(OnSessionAuthenticationFailed, void(ClientSession* client)); MOCK_METHOD1(OnSessionClosed, void(ClientSession* client)); MOCK_METHOD2(OnSessionSequenceNumber, void(ClientSession* client, diff --git a/remoting/protocol/session_config.cc b/remoting/protocol/session_config.cc index 3ce7727..1728a80 100644 --- a/remoting/protocol/session_config.cc +++ b/remoting/protocol/session_config.cc @@ -49,7 +49,7 @@ bool SessionConfig::SupportsCapabilities() const { SessionConfig SessionConfig::ForTest() { SessionConfig result; result.set_control_config(ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM, - kControlStreamVersionNoCapabilities, + kControlStreamVersion, ChannelConfig::CODEC_UNDEFINED)); result.set_event_config(ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM, kDefaultStreamVersion, diff --git a/remoting/remoting_host.gypi b/remoting/remoting_host.gypi index dc4cdc6..326536f 100644 --- a/remoting/remoting_host.gypi +++ b/remoting/remoting_host.gypi @@ -119,6 +119,8 @@ 'host/disconnect_window_win.cc', 'host/dns_blackhole_checker.cc', 'host/dns_blackhole_checker.h', + 'host/extension.h', + 'host/extension_session.h', 'host/gnubby_auth_handler_posix.cc', 'host/gnubby_auth_handler_posix.h', 'host/gnubby_auth_handler_win.cc', |