Commit 057cf3c7 authored by mattm@chromium.org's avatar mattm@chromium.org

Revert 273652 "Host extensions"

gyp failure on Win:

Exception: Missing input files:

C:\b\build\slave\Win\build\src\remoting\host\extension.h

C:\b\build\slave\Win\build\src\remoting\host\extension_session.h


> Host extensions
> 
> This CL introduces HostExtension, an interface for classes that
> extend the host with non-core functionality.
> 
> Extensions are added to the ChromotingHost. They are used to compile
> the list of capabilities reported to the client, which can be used by
> the client to determine the availability of the extension.
> 
> When a client connects, a HostExtension has the opportunity to create
> an HostExtensionSession to hold client/extension state, and to handle
> extension messages from that client.
> 
> BUG=
> 
> Review URL: https://codereview.chromium.org/301453003

TBR=dcaiafa@chromium.org

Review URL: https://codereview.chromium.org/308743006

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@273674 0039d316-1c4b-4281-b951-d872f2087c98
parent 766aef35
......@@ -141,10 +141,6 @@ 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;
......@@ -234,19 +230,6 @@ 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());
......@@ -337,13 +320,6 @@ 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);
}
......
......@@ -8,16 +8,14 @@
#include <list>
#include <string>
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/memory/ref_counted.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"
......@@ -93,9 +91,6 @@ 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.
......@@ -123,7 +118,6 @@ 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,
......@@ -160,7 +154,6 @@ 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
......@@ -211,9 +204,6 @@ 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);
......
......@@ -18,7 +18,6 @@
#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"
......@@ -99,25 +98,6 @@ 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());
......@@ -188,7 +168,6 @@ 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.
......@@ -225,13 +204,6 @@ 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: "
......@@ -281,7 +253,7 @@ void ClientSession::OnConnectionAuthenticated(
return;
}
AddHostCapabilities(desktop_environment_->GetCapabilities());
host_capabilities_ = desktop_environment_->GetCapabilities();
// Ignore protocol::Capabilities messages from the client if it does not
// support any capabilities.
......@@ -289,8 +261,6 @@ 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_);
}
......
......@@ -8,7 +8,6 @@
#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"
......@@ -16,8 +15,6 @@
#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"
......@@ -67,9 +64,6 @@ 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.
......@@ -109,13 +103,6 @@ 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;
......@@ -161,13 +148,7 @@ 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();
......@@ -263,9 +244,6 @@ 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);
};
......
......@@ -2,24 +2,17 @@
// 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"
......@@ -38,11 +31,9 @@ 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;
......@@ -51,8 +42,6 @@ using testing::StrictMock;
namespace {
const char kDefaultTestCapability[] = "default";
ACTION_P2(InjectClipboardEvent, connection, event) {
connection->clipboard_stub()->InjectClipboardEvent(event);
}
......@@ -78,75 +67,8 @@ 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") {}
......@@ -178,10 +100,6 @@ 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();
......@@ -213,41 +131,6 @@ 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(
......@@ -297,11 +180,6 @@ 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() {
......@@ -333,8 +211,7 @@ DesktopEnvironment* ClientSessionTest::CreateDesktopEnvironment() {
EXPECT_CALL(*desktop_environment, CreateVideoCapturerPtr())
.WillOnce(Invoke(this, &ClientSessionTest::CreateVideoCapturer));
EXPECT_CALL(*desktop_environment, GetCapabilities())
.Times(AtMost(1))
.WillOnce(Return(kDefaultTestCapability));
.Times(AtMost(1));
EXPECT_CALL(*desktop_environment, SetCapabilities(_))
.Times(AtMost(1));
......@@ -355,23 +232,6 @@ 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());
}
......@@ -739,63 +599,4 @@ 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
// 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_
// 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_
......@@ -71,7 +71,6 @@ 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,
......
......@@ -49,7 +49,7 @@ bool SessionConfig::SupportsCapabilities() const {
SessionConfig SessionConfig::ForTest() {
SessionConfig result;
result.set_control_config(ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM,
kControlStreamVersion,
kControlStreamVersionNoCapabilities,
ChannelConfig::CODEC_UNDEFINED));
result.set_event_config(ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM,
kDefaultStreamVersion,
......
......@@ -119,8 +119,6 @@
'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',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment