diff options
author | alexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-27 20:10:40 +0000 |
---|---|---|
committer | alexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-27 20:10:40 +0000 |
commit | a031c970f7b7a36c417214bb4bbe3fd39af9b7f1 (patch) | |
tree | 20e43413645ff528ebd63b5d0e635d53c3206568 | |
parent | 399ed423f1c7f84190a7030496ac76e9eaf945f6 (diff) | |
download | chromium_src-a031c970f7b7a36c417214bb4bbe3fd39af9b7f1.zip chromium_src-a031c970f7b7a36c417214bb4bbe3fd39af9b7f1.tar.gz chromium_src-a031c970f7b7a36c417214bb4bbe3fd39af9b7f1.tar.bz2 |
Show the disconnect window and monitor the local mouse input when running the multiprocess host.
Supporting changes in this CL:
- Desktop session agent now start only after receiving JID of the authenticated client.
- The desktop process terminates if an unknown or unexpected message is received.
BUG=134694
Review URL: https://chromiumcodereview.appspot.com/11512005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@174694 0039d316-1c4b-4281-b951-d872f2087c98
25 files changed, 300 insertions, 149 deletions
diff --git a/remoting/host/chromoting_host.cc b/remoting/host/chromoting_host.cc index 8a9c41d..9216fb0 100644 --- a/remoting/host/chromoting_host.cc +++ b/remoting/host/chromoting_host.cc @@ -373,17 +373,6 @@ void ChromotingHost::DisconnectAllClients() { } } -void ChromotingHost::DisconnectClient(DesktopEnvironment* desktop_environment) { - DCHECK(network_task_runner_->BelongsToCurrentThread()); - - for (ClientList::iterator i = clients_.begin(); i != clients_.end(); ++i) { - if ((*i)->desktop_environment() == desktop_environment) { - (*i)->Disconnect(); - break; - } - } -} - void ChromotingHost::SetUiStrings(const UiStrings& ui_strings) { DCHECK(network_task_runner_->BelongsToCurrentThread()); DCHECK_EQ(state_, kInitial); diff --git a/remoting/host/chromoting_host.h b/remoting/host/chromoting_host.h index b86cb90..5a0975e 100644 --- a/remoting/host/chromoting_host.h +++ b/remoting/host/chromoting_host.h @@ -149,9 +149,6 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>, // clients that were not connected when this method is called. void DisconnectAllClients(); - // Disconnects the client that is using |desktop_environment|, if any. - void DisconnectClient(DesktopEnvironment* desktop_environment); - const UiStrings& ui_strings() { return ui_strings_; } // Set localized strings. Must be called before host is started. diff --git a/remoting/host/chromoting_host_unittest.cc b/remoting/host/chromoting_host_unittest.cc index 2744f9a..6e7c326 100644 --- a/remoting/host/chromoting_host_unittest.cc +++ b/remoting/host/chromoting_host_unittest.cc @@ -119,7 +119,7 @@ class ChromotingHostTest : public testing::Test { base::Unretained(this))); desktop_environment_factory_.reset(new MockDesktopEnvironmentFactory()); - EXPECT_CALL(*desktop_environment_factory_, CreatePtr(_)) + EXPECT_CALL(*desktop_environment_factory_, CreatePtr()) .Times(AnyNumber()) .WillRepeatedly(Invoke(this, &ChromotingHostTest::CreateDesktopEnvironment)); @@ -282,7 +282,7 @@ class ChromotingHostTest : public testing::Test { host_->OnSessionRouteChange(get_client(0), channel_name, route); } - DesktopEnvironment* CreateDesktopEnvironment(ClientSession* client) { + DesktopEnvironment* CreateDesktopEnvironment() { scoped_ptr<EventExecutor> event_executor(new EventExecutorFake()); scoped_ptr<VideoFrameCapturer> video_capturer(new VideoFrameCapturerFake()); return new DesktopEnvironment(scoped_ptr<AudioCapturer>(NULL), diff --git a/remoting/host/chromoting_messages.h b/remoting/host/chromoting_messages.h index 214007a..846e440 100644 --- a/remoting/host/chromoting_messages.h +++ b/remoting/host/chromoting_messages.h @@ -171,9 +171,17 @@ IPC_MESSAGE_CONTROL1(ChromotingDesktopNetworkMsg_CursorShapeChanged, IPC_MESSAGE_CONTROL1(ChromotingDesktopNetworkMsg_InjectClipboardEvent, std::string /* serialized_event */ ) +// Requests the network process to terminate the client session. +IPC_MESSAGE_CONTROL0(ChromotingDesktopNetworkMsg_DisconnectSession) + //----------------------------------------------------------------------------- // Chromoting messages sent from the network to the desktop process. +// Passes the client session data to the desktop session agent and starts it. +// This must be the first message received from the host. +IPC_MESSAGE_CONTROL1(ChromotingNetworkDesktopMsg_StartSessionAgent, + std::string /* authenticated_jid */ ) + // Notifies the desktop process that the shared memory buffer has been mapped to // the memory of the network process and so it can be safely dropped by // the network process at any time. diff --git a/remoting/host/client_session.cc b/remoting/host/client_session.cc index b6137cf..f172259 100644 --- a/remoting/host/client_session.cc +++ b/remoting/host/client_session.cc @@ -38,8 +38,8 @@ ClientSession::ClientSession( const base::TimeDelta& max_duration) : event_handler_(event_handler), connection_(connection.Pass()), - desktop_environment_(desktop_environment_factory->Create( - ALLOW_THIS_IN_INITIALIZER_LIST(this))), + connection_factory_(connection_.get()), + desktop_environment_(desktop_environment_factory->Create()), client_jid_(connection_->session()->jid()), host_clipboard_stub_(desktop_environment_->event_executor()), host_input_stub_(desktop_environment_->event_executor()), @@ -129,6 +129,13 @@ void ClientSession::OnConnectionChannelsConnected( DCHECK_EQ(connection_.get(), connection); SetDisableInputs(false); + // Let the desktop environment notify us of local clipboard changes. + desktop_environment_->Start( + CreateClipboardProxy(), + client_jid(), + base::Bind(&protocol::ConnectionToClient::Disconnect, + connection_factory_.GetWeakPtr())); + // Create a VideoEncoder based on the session's video channel configuration. scoped_ptr<VideoEncoder> video_encoder = CreateVideoEncoder(connection_->session()->config()); @@ -157,9 +164,6 @@ void ClientSession::OnConnectionChannelsConnected( ++active_recorders_; } - // Let the desktop environment notify us of local clipboard changes. - desktop_environment_->Start(CreateClipboardProxy()); - // Notify the event handler that all our channels are now connected. event_handler_->OnSessionChannelsConnected(this); } @@ -170,6 +174,9 @@ void ClientSession::OnConnectionClosed( DCHECK(CalledOnValidThread()); DCHECK_EQ(connection_.get(), connection); + // Ignore any further callbacks from the DesktopEnvironment. + connection_factory_.InvalidateWeakPtrs(); + // If the client never authenticated then the session failed. if (!auth_input_filter_.enabled()) event_handler_->OnSessionAuthenticationFailed(this); diff --git a/remoting/host/client_session.h b/remoting/host/client_session.h index 07660e1..c4e0657 100644 --- a/remoting/host/client_session.h +++ b/remoting/host/client_session.h @@ -173,6 +173,9 @@ class ClientSession // The connection to the client. scoped_ptr<protocol::ConnectionToClient> connection_; + // Used to disable callbacks to |connection_| once it is disconnected. + base::WeakPtrFactory<protocol::ConnectionToClient> connection_factory_; + // The desktop environment used by this session. scoped_ptr<DesktopEnvironment> desktop_environment_; diff --git a/remoting/host/client_session_unittest.cc b/remoting/host/client_session_unittest.cc index e773122..050304c 100644 --- a/remoting/host/client_session_unittest.cc +++ b/remoting/host/client_session_unittest.cc @@ -44,7 +44,7 @@ class ClientSessionTest : public testing::Test { client_jid_ = "user@domain/rest-of-jid"; desktop_environment_factory_.reset(new MockDesktopEnvironmentFactory()); - EXPECT_CALL(*desktop_environment_factory_, CreatePtr(_)) + EXPECT_CALL(*desktop_environment_factory_, CreatePtr()) .Times(AnyNumber()) .WillRepeatedly(Invoke(this, &ClientSessionTest::CreateDesktopEnvironment)); @@ -97,7 +97,7 @@ class ClientSessionTest : public testing::Test { } protected: - DesktopEnvironment* CreateDesktopEnvironment(ClientSession* client) { + DesktopEnvironment* CreateDesktopEnvironment() { MockVideoFrameCapturer* capturer = new MockVideoFrameCapturer(); EXPECT_CALL(*capturer, Start(_)); EXPECT_CALL(*capturer, Stop()); diff --git a/remoting/host/desktop_environment.cc b/remoting/host/desktop_environment.cc index e075c8d..d862e48 100644 --- a/remoting/host/desktop_environment.cc +++ b/remoting/host/desktop_environment.cc @@ -4,6 +4,7 @@ #include "remoting/host/desktop_environment.h" +#include "base/callback.h" #include "base/compiler_specific.h" #include "remoting/capturer/video_frame_capturer.h" #include "remoting/host/audio_capturer.h" @@ -25,7 +26,9 @@ DesktopEnvironment::~DesktopEnvironment() { } void DesktopEnvironment::Start( - scoped_ptr<protocol::ClipboardStub> client_clipboard) { + scoped_ptr<protocol::ClipboardStub> client_clipboard, + const std::string& client_jid, + const base::Closure& disconnect_callback) { event_executor_->Start(client_clipboard.Pass()); } diff --git a/remoting/host/desktop_environment.h b/remoting/host/desktop_environment.h index 503f667..74b1d8e 100644 --- a/remoting/host/desktop_environment.h +++ b/remoting/host/desktop_environment.h @@ -5,7 +5,10 @@ #ifndef REMOTING_HOST_DESKTOP_ENVIRONMENT_H_ #define REMOTING_HOST_DESKTOP_ENVIRONMENT_H_ +#include <string> + #include "base/basictypes.h" +#include "base/callback_forward.h" #include "base/memory/scoped_ptr.h" namespace remoting { @@ -29,8 +32,16 @@ class DesktopEnvironment { EventExecutor* event_executor() const { return event_executor_.get(); } VideoFrameCapturer* video_capturer() const { return video_capturer_.get(); } + // Starts the desktop environment passing |client_jid| of the attached + // authenticated session. Registers |client_clipboard| to receive + // notifications about local clipboard changes. |disconnect_callback| can be + // invoked by the DesktopEnvironment to request the client session to be + // disconnected. |disconnect_callback| is invoked on the same thread Start() + // has been called on. virtual void Start( - scoped_ptr<protocol::ClipboardStub> client_clipboard); + scoped_ptr<protocol::ClipboardStub> client_clipboard, + const std::string& client_jid, + const base::Closure& disconnect_callback); private: // Used to capture audio to deliver to clients. diff --git a/remoting/host/desktop_environment_factory.cc b/remoting/host/desktop_environment_factory.cc index 0172fca..893c0cc 100644 --- a/remoting/host/desktop_environment_factory.cc +++ b/remoting/host/desktop_environment_factory.cc @@ -8,7 +8,6 @@ #include "remoting/capturer/video_frame_capturer.h" #include "remoting/host/audio_capturer.h" #include "remoting/host/chromoting_host_context.h" -#include "remoting/host/client_session.h" #include "remoting/host/desktop_environment.h" #include "remoting/host/event_executor.h" @@ -24,8 +23,7 @@ DesktopEnvironmentFactory::DesktopEnvironmentFactory( DesktopEnvironmentFactory::~DesktopEnvironmentFactory() { } -scoped_ptr<DesktopEnvironment> DesktopEnvironmentFactory::Create( - ClientSession* client) { +scoped_ptr<DesktopEnvironment> DesktopEnvironmentFactory::Create() { scoped_ptr<DesktopEnvironment> environment(new DesktopEnvironment( AudioCapturer::Create(), EventExecutor::Create(input_task_runner_, ui_task_runner_), diff --git a/remoting/host/desktop_environment_factory.h b/remoting/host/desktop_environment_factory.h index accab55..3a25437 100644 --- a/remoting/host/desktop_environment_factory.h +++ b/remoting/host/desktop_environment_factory.h @@ -15,7 +15,6 @@ class SingleThreadTaskRunner; namespace remoting { -class ClientSession; class DesktopEnvironment; class DesktopEnvironmentFactory { @@ -25,8 +24,8 @@ class DesktopEnvironmentFactory { scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner); virtual ~DesktopEnvironmentFactory(); - // Creates an instance of |DesktopEnvironment| to be used by |client|. - virtual scoped_ptr<DesktopEnvironment> Create(ClientSession* client); + // Creates an instance of |DesktopEnvironment|. + virtual scoped_ptr<DesktopEnvironment> Create(); // Returns |true| if created |DesktopEnvironment| instances support audio // capture. diff --git a/remoting/host/desktop_session_agent.cc b/remoting/host/desktop_session_agent.cc index 64492f5..a02cddb 100644 --- a/remoting/host/desktop_session_agent.cc +++ b/remoting/host/desktop_session_agent.cc @@ -13,10 +13,14 @@ #include "remoting/base/util.h" #include "remoting/capturer/capture_data.h" #include "remoting/host/chromoting_messages.h" +#include "remoting/host/disconnect_window.h" #include "remoting/host/event_executor.h" +#include "remoting/host/local_input_monitor.h" +#include "remoting/host/remote_input_filter.h" #include "remoting/proto/control.pb.h" #include "remoting/proto/event.pb.h" #include "remoting/protocol/clipboard_stub.h" +#include "remoting/protocol/input_event_tracker.h" #include "third_party/skia/include/core/SkRegion.h" namespace remoting { @@ -64,6 +68,8 @@ DesktopSessionAgent::Delegate::~Delegate() { } DesktopSessionAgent::~DesktopSessionAgent() { + DCHECK(!disconnect_window_); + DCHECK(!local_input_monitor_); DCHECK(!network_channel_); DCHECK(!video_capturer_); } @@ -72,20 +78,35 @@ bool DesktopSessionAgent::OnMessageReceived(const IPC::Message& message) { DCHECK(caller_task_runner()->BelongsToCurrentThread()); bool handled = true; - IPC_BEGIN_MESSAGE_MAP(DesktopSessionAgent, message) - IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_CaptureFrame, - OnCaptureFrame) - IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_InvalidateRegion, - OnInvalidateRegion) - IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_SharedBufferCreated, - OnSharedBufferCreated) - IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_InjectClipboardEvent, - OnInjectClipboardEvent) - IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_InjectKeyEvent, - OnInjectKeyEvent) - IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_InjectMouseEvent, - OnInjectMouseEvent) - IPC_END_MESSAGE_MAP() + if (started_) { + IPC_BEGIN_MESSAGE_MAP(DesktopSessionAgent, message) + IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_CaptureFrame, + OnCaptureFrame) + IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_InvalidateRegion, + OnInvalidateRegion) + IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_SharedBufferCreated, + OnSharedBufferCreated) + IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_InjectClipboardEvent, + OnInjectClipboardEvent) + IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_InjectKeyEvent, + OnInjectKeyEvent) + IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_InjectMouseEvent, + OnInjectMouseEvent) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + } else { + IPC_BEGIN_MESSAGE_MAP(DesktopSessionAgent, message) + IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_StartSessionAgent, + OnStartSessionAgent) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + } + + // Close the channel if the received message wasn't expected. + if (!handled) { + LOG(ERROR) << "An unexpected IPC message received: type=" << message.type(); + OnChannelError(); + } return handled; } @@ -107,6 +128,12 @@ void DesktopSessionAgent::OnChannelError() { delegate_->OnNetworkProcessDisconnected(); } +void DesktopSessionAgent::OnLocalMouseMoved(const SkIPoint& new_pos) { + DCHECK(caller_task_runner()->BelongsToCurrentThread()); + + remote_input_filter_->LocalMouseMoved(new_pos); +} + scoped_refptr<SharedBuffer> DesktopSessionAgent::CreateSharedBuffer( uint32 size) { DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); @@ -142,6 +169,43 @@ void DesktopSessionAgent::ReleaseSharedBuffer( new ChromotingDesktopNetworkMsg_ReleaseSharedBuffer(buffer->id())); } +void DesktopSessionAgent::OnStartSessionAgent( + const std::string& authenticated_jid) { + DCHECK(caller_task_runner()->BelongsToCurrentThread()); + DCHECK(!started_); + + started_ = true; + + // Create the event executor. + event_executor_ = CreateEventExecutor(); + + // Hook up the input filter + input_tracker_.reset(new protocol::InputEventTracker(event_executor_.get())); + remote_input_filter_.reset(new RemoteInputFilter(input_tracker_.get())); + + // Start the event executor. + scoped_ptr<protocol::ClipboardStub> clipboard_stub( + new DesktopSesssionClipboardStub(this)); + event_executor_->Start(clipboard_stub.Pass()); + + base::Closure disconnect_session = + base::Bind(&DesktopSessionAgent::DisconnectSession, this); + + // Create the disconnect window. + disconnect_window_ = DisconnectWindow::Create(); + disconnect_window_->Show( + ui_strings_, disconnect_session, + authenticated_jid.substr(0, authenticated_jid.find('/'))); + + // Start monitoring local input. + local_input_monitor_ = LocalInputMonitor::Create(); + local_input_monitor_->Start(this, disconnect_session); + + // Start the video capturer. + video_capture_task_runner()->PostTask( + FROM_HERE, base::Bind(&DesktopSessionAgent::StartVideoCapturer, this)); +} + void DesktopSessionAgent::OnCaptureCompleted( scoped_refptr<CaptureData> capture_data) { DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); @@ -192,19 +256,7 @@ bool DesktopSessionAgent::Start(const base::WeakPtr<Delegate>& delegate, delegate_ = delegate; // Create an IPC channel to communicate with the network process. - if (!CreateChannelForNetworkProcess(desktop_pipe_out, &network_channel_)) - return false; - - // Create and start the event executor. - event_executor_ = CreateEventExecutor(); - scoped_ptr<protocol::ClipboardStub> clipboard_stub( - new DesktopSesssionClipboardStub(this)); - event_executor_->Start(clipboard_stub.Pass()); - - // Start the video capturer. - video_capture_task_runner()->PostTask( - FROM_HERE, base::Bind(&DesktopSessionAgent::StartVideoCapturer, this)); - return true; + return CreateChannelForNetworkProcess(desktop_pipe_out, &network_channel_); } void DesktopSessionAgent::Stop() { @@ -215,11 +267,29 @@ void DesktopSessionAgent::Stop() { // Make sure the channel is closed. network_channel_.reset(); - event_executor_.reset(); + if (started_) { + started_ = false; - // Stop the video capturer. - video_capture_task_runner()->PostTask( - FROM_HERE, base::Bind(&DesktopSessionAgent::StopVideoCapturer, this)); + // Close the disconnect window and stop listening to local input. + disconnect_window_->Hide(); + disconnect_window_.reset(); + + // Stop monitoring to local input. + local_input_monitor_->Stop(); + local_input_monitor_.reset(); + + remote_input_filter_.reset(); + + // Ensure that any pressed keys or buttons are released. + input_tracker_->ReleaseAll(); + input_tracker_.reset(); + + event_executor_.reset(); + + // Stop the video capturer. + video_capture_task_runner()->PostTask( + FROM_HERE, base::Bind(&DesktopSessionAgent::StopVideoCapturer, this)); + } } void DesktopSessionAgent::OnCaptureFrame() { @@ -323,7 +393,7 @@ void DesktopSessionAgent::OnInjectKeyEvent( return; } - event_executor_->InjectKeyEvent(event); + remote_input_filter_->InjectKeyEvent(event); } void DesktopSessionAgent::OnInjectMouseEvent( @@ -350,7 +420,11 @@ void DesktopSessionAgent::OnInjectMouseEvent( if (event.has_y()) event.set_y(std::max(0, event.y())); - event_executor_->InjectMouseEvent(event); + remote_input_filter_->InjectMouseEvent(event); +} + +void DesktopSessionAgent::DisconnectSession() { + SendToNetwork(new ChromotingDesktopNetworkMsg_DisconnectSession()); } void DesktopSessionAgent::SendToNetwork(IPC::Message* message) { @@ -397,7 +471,8 @@ DesktopSessionAgent::DesktopSessionAgent( input_task_runner_(input_task_runner), io_task_runner_(io_task_runner), video_capture_task_runner_(video_capture_task_runner), - next_shared_buffer_id_(1) { + next_shared_buffer_id_(1), + started_(false) { DCHECK(caller_task_runner_->BelongsToCurrentThread()); } diff --git a/remoting/host/desktop_session_agent.h b/remoting/host/desktop_session_agent.h index 6edfa73..916b4a5 100644 --- a/remoting/host/desktop_session_agent.h +++ b/remoting/host/desktop_session_agent.h @@ -18,6 +18,8 @@ #include "remoting/capturer/shared_buffer.h" #include "remoting/capturer/shared_buffer_factory.h" #include "remoting/capturer/video_frame_capturer.h" +#include "remoting/host/mouse_move_observer.h" +#include "remoting/host/ui_strings.h" #include "remoting/protocol/clipboard_stub.h" #include "third_party/skia/include/core/SkRect.h" @@ -29,13 +31,21 @@ class Message; namespace remoting { class AutoThreadTaskRunner; +class DisconnectWindow; class EventExecutor; +class LocalInputMonitor; +class RemoteInputFilter; + +namespace protocol { +class InputEventTracker; +} // namespace protocol // Provides screen/audio capturing and input injection services for // the network process. class DesktopSessionAgent : public base::RefCountedThreadSafe<DesktopSessionAgent>, public IPC::Listener, + public MouseMoveObserver, public SharedBufferFactory, public VideoFrameCapturer::Delegate { public: @@ -62,6 +72,9 @@ class DesktopSessionAgent virtual void OnChannelConnected(int32 peer_pid) OVERRIDE; virtual void OnChannelError() OVERRIDE; + // MouseMoveObserver implementation. + virtual void OnLocalMouseMoved(const SkIPoint& new_pos) OVERRIDE; + // SharedBufferFactory implementation. virtual scoped_refptr<SharedBuffer> CreateSharedBuffer(uint32 size) OVERRIDE; virtual void ReleaseSharedBuffer(scoped_refptr<SharedBuffer> buffer) OVERRIDE; @@ -104,6 +117,9 @@ class DesktopSessionAgent // Creates an event executor specific to the platform. virtual scoped_ptr<EventExecutor> CreateEventExecutor() = 0; + // Handles StartSessionAgent request from the client. + void OnStartSessionAgent(const std::string& authenticated_jid); + // Handles CaptureFrame requests from the client. void OnCaptureFrame(); @@ -118,6 +134,9 @@ class DesktopSessionAgent void OnInjectKeyEvent(const std::string& serialized_event); void OnInjectMouseEvent(const std::string& serialized_event); + // Sends DisconnectSession request to the host. + void DisconnectSession(); + // Sends a message to the network process. void SendToNetwork(IPC::Message* message); @@ -164,9 +183,22 @@ class DesktopSessionAgent base::WeakPtr<Delegate> delegate_; + // Provides a user interface allowing the local user to close the connection. + scoped_ptr<DisconnectWindow> disconnect_window_; + // Executes keyboard, mouse and clipboard events. scoped_ptr<EventExecutor> event_executor_; + // Monitor local inputs to allow remote inputs to be blocked while the local + // user is trying to do something. + scoped_ptr<LocalInputMonitor> local_input_monitor_; + + // Tracker used to release pressed keys and buttons when disconnecting. + scoped_ptr<protocol::InputEventTracker> input_tracker_; + + // Filter used to disable remote inputs during local input activity. + scoped_ptr<RemoteInputFilter> remote_input_filter_; + // IPC channel connecting the desktop process with the network process. scoped_ptr<IPC::ChannelProxy> network_channel_; @@ -177,9 +209,14 @@ class DesktopSessionAgent typedef std::list<scoped_refptr<SharedBuffer> > SharedBuffers; SharedBuffers shared_buffers_; + // True if the desktop session agent has been started. + bool started_; + // Captures the screen. scoped_ptr<VideoFrameCapturer> video_capturer_; + UiStrings ui_strings_; + DISALLOW_COPY_AND_ASSIGN(DesktopSessionAgent); }; diff --git a/remoting/host/desktop_session_connector.h b/remoting/host/desktop_session_connector.h index 5537574..60ea8ac 100644 --- a/remoting/host/desktop_session_connector.h +++ b/remoting/host/desktop_session_connector.h @@ -6,11 +6,12 @@ #define REMOTING_HOST_DESKTOP_SESSION_CONNECTOR_H_ #include "base/basictypes.h" +#include "base/memory/ref_counted.h" #include "ipc/ipc_platform_file.h" namespace remoting { -class IpcDesktopEnvironment; +class DesktopSessionProxy; // Provides a way to connect a terminal (i.e. a remote client) with a desktop // session (i.e. the screen, keyboard and the rest). @@ -20,13 +21,14 @@ class DesktopSessionConnector { virtual ~DesktopSessionConnector() {} // Requests the daemon process to create a desktop session and associates - // |desktop_environment| with it. - virtual void ConnectTerminal(IpcDesktopEnvironment* desktop_environment) = 0; + // |desktop_session_proxy| with it. + virtual void ConnectTerminal( + scoped_refptr<DesktopSessionProxy> desktop_session_proxy) = 0; - // Requests the daemon process disconnect |desktop_environment| from + // Requests the daemon process disconnect |desktop_session_proxy| from // the associated desktop session. virtual void DisconnectTerminal( - IpcDesktopEnvironment* desktop_environment) = 0; + scoped_refptr<DesktopSessionProxy> desktop_session_proxy) = 0; // Notifies the network process that |terminal_id| is now attached to // a desktop integration process. |desktop_process| specifies the process diff --git a/remoting/host/desktop_session_proxy.cc b/remoting/host/desktop_session_proxy.cc index 6489df45..3f2f62f 100644 --- a/remoting/host/desktop_session_proxy.cc +++ b/remoting/host/desktop_session_proxy.cc @@ -13,6 +13,7 @@ #include "remoting/capturer/capture_data.h" #include "remoting/host/audio_capturer.h" #include "remoting/host/chromoting_messages.h" +#include "remoting/host/client_session.h" #include "remoting/host/ipc_video_frame_capturer.h" #include "remoting/proto/control.pb.h" #include "remoting/proto/event.pb.h" @@ -30,6 +31,7 @@ DesktopSessionProxy::DesktopSessionProxy( video_capture_task_runner_(video_capture_task_runner), pending_capture_frame_requests_(0), video_capturer_(NULL) { + DCHECK(caller_task_runner_->BelongsToCurrentThread()); } bool DesktopSessionProxy::OnMessageReceived(const IPC::Message& message) { @@ -47,6 +49,8 @@ bool DesktopSessionProxy::OnMessageReceived(const IPC::Message& message) { OnReleaseSharedBuffer) IPC_MESSAGE_HANDLER(ChromotingDesktopNetworkMsg_InjectClipboardEvent, OnInjectClipboardEvent) + IPC_MESSAGE_HANDLER(ChromotingDesktopNetworkMsg_DisconnectSession, + DisconnectSession); IPC_END_MESSAGE_MAP() return handled; @@ -61,13 +65,28 @@ void DesktopSessionProxy::OnChannelConnected(int32 peer_pid) { void DesktopSessionProxy::OnChannelError() { DCHECK(caller_task_runner_->BelongsToCurrentThread()); - Disconnect(); + DetachFromDesktop(); +} + +void DesktopSessionProxy::Initialize(const std::string& client_jid, + const base::Closure& disconnect_callback) { + DCHECK(caller_task_runner_->BelongsToCurrentThread()); + DCHECK(client_jid_.empty()); + DCHECK(!client_jid.empty()); + DCHECK(disconnect_callback_.is_null()); + DCHECK(!disconnect_callback.is_null()); + + client_jid_ = client_jid; + disconnect_callback_ = disconnect_callback; } -bool DesktopSessionProxy::Connect(IPC::PlatformFileForTransit desktop_process, - IPC::PlatformFileForTransit desktop_pipe) { +bool DesktopSessionProxy::AttachToDesktop( + IPC::PlatformFileForTransit desktop_process, + IPC::PlatformFileForTransit desktop_pipe) { DCHECK(caller_task_runner_->BelongsToCurrentThread()); + DCHECK(!client_jid_.empty()); DCHECK(!desktop_channel_); + DCHECK(!disconnect_callback_.is_null()); #if defined(OS_WIN) // On Windows: |desktop_process| is a valid handle, but |desktop_pipe| needs @@ -105,10 +124,13 @@ bool DesktopSessionProxy::Connect(IPC::PlatformFileForTransit desktop_process, #error Unsupported platform. #endif + // Pass ID of the client (which is authenticated at this point) to the desktop + // session agent and start the agent. + SendToDesktop(new ChromotingNetworkDesktopMsg_StartSessionAgent(client_jid_)); return true; } -void DesktopSessionProxy::Disconnect() { +void DesktopSessionProxy::DetachFromDesktop() { DCHECK(caller_task_runner_->BelongsToCurrentThread()); desktop_channel_.reset(); @@ -126,6 +148,13 @@ void DesktopSessionProxy::Disconnect() { } } +void DesktopSessionProxy::DisconnectSession() { + DCHECK(caller_task_runner_->BelongsToCurrentThread()); + + // Disconnect the client session if it hasn't been disconnected yet. + disconnect_callback_.Run(); +} + void DesktopSessionProxy::InjectClipboardEvent( const protocol::ClipboardEvent& event) { DCHECK(caller_task_runner_->BelongsToCurrentThread()); @@ -326,7 +355,6 @@ void DesktopSessionProxy::OnInjectClipboardEvent( client_clipboard_->InjectClipboardEvent(event); } - void DesktopSessionProxy::PostCaptureCompleted( scoped_refptr<CaptureData> capture_data) { if (!video_capture_task_runner_->BelongsToCurrentThread()) { diff --git a/remoting/host/desktop_session_proxy.h b/remoting/host/desktop_session_proxy.h index 43b6208..5c5dab2 100644 --- a/remoting/host/desktop_session_proxy.h +++ b/remoting/host/desktop_session_proxy.h @@ -10,6 +10,7 @@ #include "base/basictypes.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" #include "ipc/ipc_listener.h" #include "ipc/ipc_platform_file.h" #include "remoting/capturer/shared_buffer.h" @@ -35,6 +36,7 @@ struct SerializedCapturedData; namespace remoting { +class ClientSession; class IpcVideoFrameCapturer; // This class routes calls to the DesktopEnvironment's stubs though the IPC @@ -53,13 +55,23 @@ class DesktopSessionProxy virtual void OnChannelConnected(int32 peer_pid) OVERRIDE; virtual void OnChannelError() OVERRIDE; - // Connects to the desktop process. - bool Connect(IPC::PlatformFileForTransit desktop_process, - IPC::PlatformFileForTransit desktop_pipe); + // Initializes the object. |client_jid| specifies the client session's JID. + // |disconnect_callback| specifies a callback that disconnects the client + // session when invoked. + // Initialize() should be called before AttachToDesktop() is called. + void Initialize(const std::string& client_jid, + const base::Closure& disconnect_callback); + + // Connects to the desktop session agent. + bool AttachToDesktop(IPC::PlatformFileForTransit desktop_process, + IPC::PlatformFileForTransit desktop_pipe); // Closes the connection to the desktop session agent and cleans up // the associated resources. - void Disconnect(); + void DetachFromDesktop(); + + // Disconnects the client session that owns |this|. + void DisconnectSession(); // APIs used to implement the VideoFrameCapturer interface. These must be // called on |video_capture_task_runner_|. @@ -101,6 +113,9 @@ class DesktopSessionProxy // Handles CursorShapeChanged notification from the desktop session agent. void OnCursorShapeChanged(const MouseCursorShape& cursor_shape); + // Handles InjectClipboardEvent request from the desktop integration process. + void OnInjectClipboardEvent(const std::string& serialized_event); + // Posted to |video_capture_task_runner_| to pass a captured video frame back // to |video_capturer_|. void PostCaptureCompleted(scoped_refptr<CaptureData> capture_data); @@ -109,9 +124,6 @@ class DesktopSessionProxy // |video_capturer_|. void PostCursorShape(scoped_ptr<MouseCursorShape> cursor_shape); - // Handles InjectClipboardEvent request from the desktop integration process. - void OnInjectClipboardEvent(const std::string& serialized_event); - // Sends a message to the desktop session agent. The message is silently // deleted if the channel is broken. void SendToDesktop(IPC::Message* message); @@ -126,9 +138,15 @@ class DesktopSessionProxy // Points to the client stub passed to StartEventExecutor(). scoped_ptr<protocol::ClipboardStub> client_clipboard_; + // JID of the client session. + std::string client_jid_; + // IPC channel to the desktop session agent. scoped_ptr<IPC::ChannelProxy> desktop_channel_; + // Disconnects the client session when invoked. + base::Closure disconnect_callback_; + #if defined(OS_WIN) // Handle of the desktop process. base::win::ScopedHandle desktop_process_; diff --git a/remoting/host/host_mock_objects.cc b/remoting/host/host_mock_objects.cc index cb4dddd..f9b6c52 100644 --- a/remoting/host/host_mock_objects.cc +++ b/remoting/host/host_mock_objects.cc @@ -18,9 +18,8 @@ MockDesktopEnvironmentFactory::MockDesktopEnvironmentFactory() MockDesktopEnvironmentFactory::~MockDesktopEnvironmentFactory() {} -scoped_ptr<DesktopEnvironment> MockDesktopEnvironmentFactory::Create( - ClientSession* client) { - return scoped_ptr<DesktopEnvironment>(CreatePtr(client)); +scoped_ptr<DesktopEnvironment> MockDesktopEnvironmentFactory::Create() { + return scoped_ptr<DesktopEnvironment>(CreatePtr()); } MockEventExecutor::MockEventExecutor() {} diff --git a/remoting/host/host_mock_objects.h b/remoting/host/host_mock_objects.h index 8a2fae6..e8dd33a 100644 --- a/remoting/host/host_mock_objects.h +++ b/remoting/host/host_mock_objects.h @@ -80,9 +80,9 @@ class MockDesktopEnvironmentFactory : public DesktopEnvironmentFactory { MockDesktopEnvironmentFactory(); virtual ~MockDesktopEnvironmentFactory(); - MOCK_METHOD1(CreatePtr, DesktopEnvironment*(ClientSession* client)); + MOCK_METHOD0(CreatePtr, DesktopEnvironment*()); - virtual scoped_ptr<DesktopEnvironment> Create(ClientSession* client) OVERRIDE; + virtual scoped_ptr<DesktopEnvironment> Create() OVERRIDE; private: DISALLOW_COPY_AND_ASSIGN(MockDesktopEnvironmentFactory); diff --git a/remoting/host/ipc_desktop_environment.cc b/remoting/host/ipc_desktop_environment.cc index 26945f2..6229adb 100644 --- a/remoting/host/ipc_desktop_environment.cc +++ b/remoting/host/ipc_desktop_environment.cc @@ -4,6 +4,7 @@ #include "remoting/host/ipc_desktop_environment.h" +#include "base/callback.h" #include "base/compiler_specific.h" #include "base/logging.h" #include "base/platform_file.h" @@ -32,8 +33,7 @@ IpcDesktopEnvironment::IpcDesktopEnvironment( scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, DesktopSessionConnector* desktop_session_connector, - scoped_refptr<DesktopSessionProxy> desktop_session_proxy, - ClientSession* client) + scoped_refptr<DesktopSessionProxy> desktop_session_proxy) : DesktopEnvironment( AudioCapturer::Create(), scoped_ptr<EventExecutor>( @@ -42,7 +42,6 @@ IpcDesktopEnvironment::IpcDesktopEnvironment( new IpcVideoFrameCapturer(desktop_session_proxy))), network_task_runner_(network_task_runner), desktop_session_connector_(desktop_session_connector), - client_(client), desktop_session_proxy_(desktop_session_proxy), connected_(false) { } @@ -50,34 +49,26 @@ IpcDesktopEnvironment::IpcDesktopEnvironment( IpcDesktopEnvironment::~IpcDesktopEnvironment() { if (connected_) { connected_ = false; - desktop_session_connector_->DisconnectTerminal(this); + desktop_session_connector_->DisconnectTerminal(desktop_session_proxy_); } } void IpcDesktopEnvironment::Start( - scoped_ptr<protocol::ClipboardStub> client_clipboard) { + scoped_ptr<protocol::ClipboardStub> client_clipboard, + const std::string& client_jid, + const base::Closure& disconnect_callback) { DCHECK(network_task_runner_->BelongsToCurrentThread()); DCHECK(!connected_); - connected_ = true; - desktop_session_connector_->ConnectTerminal(this); - - DesktopEnvironment::Start(client_clipboard.Pass()); -} - -void IpcDesktopEnvironment::DisconnectClient() { - DCHECK(network_task_runner_->BelongsToCurrentThread()); + desktop_session_proxy_->Initialize(client_jid, disconnect_callback); - client_->Disconnect(); -} - -void IpcDesktopEnvironment::OnDesktopSessionAgentAttached( - IPC::PlatformFileForTransit desktop_process, - IPC::PlatformFileForTransit desktop_pipe) { - DCHECK(network_task_runner_->BelongsToCurrentThread()); + // Register the proxy to receive AttachToDesktop() and DetachFromDesktop() + // notifications. + connected_ = true; + desktop_session_connector_->ConnectTerminal(desktop_session_proxy_); - desktop_session_proxy_->Disconnect(); - desktop_session_proxy_->Connect(desktop_process, desktop_pipe); + DesktopEnvironment::Start(client_clipboard.Pass(), client_jid, + disconnect_callback); } } // namespace remoting diff --git a/remoting/host/ipc_desktop_environment.h b/remoting/host/ipc_desktop_environment.h index 8ec721b..53b5c0f 100644 --- a/remoting/host/ipc_desktop_environment.h +++ b/remoting/host/ipc_desktop_environment.h @@ -6,6 +6,7 @@ #define REMOTING_HOST_IPC_DESKTOP_ENVIRONMENT_H_ #include "base/basictypes.h" +#include "base/callback_forward.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "ipc/ipc_platform_file.h" @@ -17,7 +18,6 @@ class SingleThreadTaskRunner; namespace remoting { -class ClientSession; class DesktopSessionConnector; class DesktopSessionProxy; @@ -34,22 +34,13 @@ class IpcDesktopEnvironment : public DesktopEnvironment { scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, DesktopSessionConnector* desktop_session_connector, - scoped_refptr<DesktopSessionProxy> desktop_session_proxy, - ClientSession* client); + scoped_refptr<DesktopSessionProxy> desktop_session_proxy); virtual ~IpcDesktopEnvironment(); virtual void Start( - scoped_ptr<protocol::ClipboardStub> client_clipboard) OVERRIDE; - - // Disconnects the client session that owns |this|. - void DisconnectClient(); - - // Notifies |this| that it is now attached to a desktop integration process. - // |desktop_process| specifies the process handle. |desktop_pipe| is - // the client end of the pipe opened by the desktop process. - void OnDesktopSessionAgentAttached( - IPC::PlatformFileForTransit desktop_process, - IPC::PlatformFileForTransit desktop_pipe); + scoped_ptr<protocol::ClipboardStub> client_clipboard, + const std::string& client_jid, + const base::Closure& disconnect_callback) OVERRIDE; private: // Used for IPC I/O. @@ -57,9 +48,6 @@ class IpcDesktopEnvironment : public DesktopEnvironment { DesktopSessionConnector* desktop_session_connector_; - // Specifies the client session that owns |this|. - ClientSession* client_; - scoped_refptr<DesktopSessionProxy> desktop_session_proxy_; // True if |this| has been connected to a desktop session. diff --git a/remoting/host/ipc_desktop_environment_factory.cc b/remoting/host/ipc_desktop_environment_factory.cc index b587262..2996ec5 100644 --- a/remoting/host/ipc_desktop_environment_factory.cc +++ b/remoting/host/ipc_desktop_environment_factory.cc @@ -36,8 +36,7 @@ IpcDesktopEnvironmentFactory::IpcDesktopEnvironmentFactory( IpcDesktopEnvironmentFactory::~IpcDesktopEnvironmentFactory() { } -scoped_ptr<DesktopEnvironment> IpcDesktopEnvironmentFactory::Create( - ClientSession* client) { +scoped_ptr<DesktopEnvironment> IpcDesktopEnvironmentFactory::Create() { DCHECK(network_task_runner_->BelongsToCurrentThread()); scoped_refptr<DesktopSessionProxy> desktop_session_proxy( @@ -46,16 +45,16 @@ scoped_ptr<DesktopEnvironment> IpcDesktopEnvironmentFactory::Create( return scoped_ptr<DesktopEnvironment>(new IpcDesktopEnvironment( input_task_runner_, network_task_runner_, ui_task_runner_, - this, desktop_session_proxy, client)); + this, desktop_session_proxy)); } void IpcDesktopEnvironmentFactory::ConnectTerminal( - IpcDesktopEnvironment* desktop_environment) { + scoped_refptr<DesktopSessionProxy> desktop_session_proxy) { DCHECK(network_task_runner_->BelongsToCurrentThread()); int id = next_id_++; bool inserted = active_connections_.insert( - std::make_pair(id, desktop_environment)).second; + std::make_pair(id, desktop_session_proxy)).second; CHECK(inserted); VLOG(1) << "Network: registered desktop environment " << id; @@ -63,12 +62,12 @@ void IpcDesktopEnvironmentFactory::ConnectTerminal( } void IpcDesktopEnvironmentFactory::DisconnectTerminal( - IpcDesktopEnvironment* desktop_environment) { + scoped_refptr<DesktopSessionProxy> desktop_session_proxy) { DCHECK(network_task_runner_->BelongsToCurrentThread()); ActiveConnectionsList::iterator i; for (i = active_connections_.begin(); i != active_connections_.end(); ++i) { - if (i->second == desktop_environment) + if (i->second.get() == desktop_session_proxy.get()) break; } @@ -94,7 +93,8 @@ void IpcDesktopEnvironmentFactory::OnDesktopSessionAgentAttached( ActiveConnectionsList::iterator i = active_connections_.find(terminal_id); if (i != active_connections_.end()) { - i->second->OnDesktopSessionAgentAttached(desktop_process, desktop_pipe); + i->second->DetachFromDesktop(); + i->second->AttachToDesktop(desktop_process, desktop_pipe); } else { #if defined(OS_POSIX) DCHECK(desktop_process.auto_close); @@ -118,11 +118,11 @@ void IpcDesktopEnvironmentFactory::OnTerminalDisconnected(int terminal_id) { ActiveConnectionsList::iterator i = active_connections_.find(terminal_id); if (i != active_connections_.end()) { - IpcDesktopEnvironment* desktop_environment = i->second; + scoped_refptr<DesktopSessionProxy> desktop_session_proxy = i->second; active_connections_.erase(i); - // Disconnect the client for the given desktop environment. - desktop_environment->DisconnectClient(); + // Disconnect the client session. + desktop_session_proxy->DisconnectSession(); } } diff --git a/remoting/host/ipc_desktop_environment_factory.h b/remoting/host/ipc_desktop_environment_factory.h index 2b0ebfe..435ea6d 100644 --- a/remoting/host/ipc_desktop_environment_factory.h +++ b/remoting/host/ipc_desktop_environment_factory.h @@ -7,6 +7,7 @@ #include <map> +#include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "remoting/host/desktop_environment_factory.h" #include "remoting/host/desktop_session_connector.h" @@ -18,7 +19,7 @@ class ChannelProxy; namespace remoting { class DesktopSessionConnector; -class IpcDesktopEnvironment; +class DesktopSessionProxy; // Used to create IpcDesktopEnvironment objects intergating with the desktop via // a helper process and talking to that process via IPC. @@ -36,13 +37,13 @@ class IpcDesktopEnvironmentFactory scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner); virtual ~IpcDesktopEnvironmentFactory(); - virtual scoped_ptr<DesktopEnvironment> Create(ClientSession* client) OVERRIDE; + virtual scoped_ptr<DesktopEnvironment> Create() OVERRIDE; // DesktopSessionConnector implementation. virtual void ConnectTerminal( - IpcDesktopEnvironment* desktop_environment) OVERRIDE; + scoped_refptr<DesktopSessionProxy> desktop_session_proxy) OVERRIDE; virtual void DisconnectTerminal( - IpcDesktopEnvironment* desktop_environment) OVERRIDE; + scoped_refptr<DesktopSessionProxy> desktop_session_proxy) OVERRIDE; virtual void OnDesktopSessionAgentAttached( int terminal_id, IPC::PlatformFileForTransit desktop_process, @@ -60,7 +61,8 @@ class IpcDesktopEnvironmentFactory scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner_; // List of DesktopEnvironment instances we've told the daemon process about. - typedef std::map<int, IpcDesktopEnvironment*> ActiveConnectionsList; + typedef std::map<int, scoped_refptr<DesktopSessionProxy> > + ActiveConnectionsList; ActiveConnectionsList active_connections_; // Next desktop session ID. IDs are allocated sequentially starting from 0. diff --git a/remoting/host/remoting_me2me_host.cc b/remoting/host/remoting_me2me_host.cc index 0d2fc6b..8d1d349 100644 --- a/remoting/host/remoting_me2me_host.cc +++ b/remoting/host/remoting_me2me_host.cc @@ -592,7 +592,7 @@ void HostProcess::StartOnUiThread() { // The host UI should be created on the UI thread. bool want_user_interface = true; -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(REMOTING_MULTI_PROCESS) want_user_interface = false; #elif defined(OS_MACOSX) // Don't try to display any UI on top of the system's login screen as this diff --git a/remoting/host/win/session_desktop_environment_factory.cc b/remoting/host/win/session_desktop_environment_factory.cc index 583361e..e0c8fb7 100644 --- a/remoting/host/win/session_desktop_environment_factory.cc +++ b/remoting/host/win/session_desktop_environment_factory.cc @@ -8,7 +8,6 @@ #include "remoting/capturer/video_frame_capturer.h" #include "remoting/host/audio_capturer.h" #include "remoting/host/chromoting_host_context.h" -#include "remoting/host/client_session.h" #include "remoting/host/desktop_environment.h" #include "remoting/host/event_executor.h" #include "remoting/host/win/session_event_executor.h" @@ -26,8 +25,7 @@ SessionDesktopEnvironmentFactory::SessionDesktopEnvironmentFactory( SessionDesktopEnvironmentFactory::~SessionDesktopEnvironmentFactory() { } -scoped_ptr<DesktopEnvironment> SessionDesktopEnvironmentFactory::Create( - ClientSession* client) { +scoped_ptr<DesktopEnvironment> SessionDesktopEnvironmentFactory::Create() { scoped_ptr<AudioCapturer> audio_capturer = AudioCapturer::Create(); scoped_ptr<EventExecutor> event_executor = EventExecutor::Create( input_task_runner_, ui_task_runner_); diff --git a/remoting/host/win/session_desktop_environment_factory.h b/remoting/host/win/session_desktop_environment_factory.h index a5b6d6e..99998fb6 100644 --- a/remoting/host/win/session_desktop_environment_factory.h +++ b/remoting/host/win/session_desktop_environment_factory.h @@ -10,8 +10,6 @@ namespace remoting { -class ClientSession; - class SessionDesktopEnvironmentFactory : public DesktopEnvironmentFactory { public: SessionDesktopEnvironmentFactory( @@ -20,7 +18,7 @@ class SessionDesktopEnvironmentFactory : public DesktopEnvironmentFactory { const base::Closure& inject_sas); virtual ~SessionDesktopEnvironmentFactory(); - virtual scoped_ptr<DesktopEnvironment> Create(ClientSession* client) OVERRIDE; + virtual scoped_ptr<DesktopEnvironment> Create() OVERRIDE; private: // Used to ask the daemon to inject Secure Attention Sequence. |