// Copyright (c) 2011 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_CHROMOTING_HOST_H_ #define REMOTING_CHROMOTING_HOST_H_ #include <string> #include "base/memory/scoped_ptr.h" #include "base/threading/thread.h" #include "base/timer.h" #include "remoting/base/encoder.h" #include "remoting/host/access_verifier.h" #include "remoting/host/capturer.h" #include "remoting/host/client_session.h" #include "remoting/host/desktop_environment.h" #include "remoting/host/host_status_observer.h" #include "remoting/jingle_glue/jingle_client.h" #include "remoting/jingle_glue/jingle_thread.h" #include "remoting/protocol/session_manager.h" #include "remoting/protocol/connection_to_client.h" class Task; namespace remoting { namespace protocol { class ConnectionToClient; class HostStub; class InputStub; class SessionConfig; class CandidateSessionConfig; } // namespace protocol class Capturer; class ChromotingHostContext; class DesktopEnvironment; class Encoder; class MutableHostConfig; class ScreenRecorder; // A class to implement the functionality of a host process. // // Here's the work flow of this class: // 1. We should load the saved GAIA ID token or if this is the first // time the host process runs we should prompt user for the // credential. We will use this token or credentials to authenicate // and register the host. // // 2. We listen for incoming connection using libjingle. We will create // a ConnectionToClient object that wraps around linjingle for transport. // A ScreenRecorder is created with an Encoder and a Capturer. // A ConnectionToClient is added to the ScreenRecorder for transporting // the screen captures. An InputStub is created and registered with the // ConnectionToClient to receive mouse / keyboard events from the remote // client. // After we have done all the initialization we'll start the ScreenRecorder. // We'll then enter the running state of the host process. // // 3. When the user is disconnected, we will pause the ScreenRecorder // and try to terminate the threads we have created. This will allow // all pending tasks to complete. After all of that completed we // return to the idle state. We then go to step (2) if there a new // incoming connection. class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>, public protocol::ConnectionToClient::EventHandler, public ClientSession::EventHandler, public JingleClient::Callback { public: // Factory methods that must be used to create ChromotingHost instances. // Default capturer and input stub are used if it is not specified. // Returned instance takes ownership of |access_verifier| and |environment|, // and adds a reference to |config|. It does NOT take ownership of |context|. static ChromotingHost* Create(ChromotingHostContext* context, MutableHostConfig* config, AccessVerifier* access_verifier); static ChromotingHost* Create(ChromotingHostContext* context, MutableHostConfig* config, DesktopEnvironment* environment, AccessVerifier* access_verifier); // Asynchronously start the host process. // // After this is invoked, the host process will connect to the talk // network and start listening for incoming connections. // // This method can only be called once during the lifetime of this object. void Start(); // Asynchronously shutdown the host process. |shutdown_task| is // called after shutdown is completed. void Shutdown(Task* shutdown_task); // Adds |observer| to the list of status observers. Doesn't take // ownership of |observer|, so |observer| must outlive this // object. All status observers must be added before the host is // started. void AddStatusObserver(HostStatusObserver* observer); //////////////////////////////////////////////////////////////////////////// // protocol::ConnectionToClient::EventHandler implementations virtual void OnConnectionOpened(protocol::ConnectionToClient* client); virtual void OnConnectionClosed(protocol::ConnectionToClient* client); virtual void OnConnectionFailed(protocol::ConnectionToClient* client); virtual void OnSequenceNumberUpdated(protocol::ConnectionToClient* client, int64 sequence_number); //////////////////////////////////////////////////////////////////////////// // JingleClient::Callback implementations virtual void OnStateChange(JingleClient* client, JingleClient::State state); //////////////////////////////////////////////////////////////////////////// // ClientSession::EventHandler implementations virtual void LocalLoginSucceeded( scoped_refptr<protocol::ConnectionToClient> client); virtual void LocalLoginFailed( scoped_refptr<protocol::ConnectionToClient> client); // Callback for ChromotingServer. void OnNewClientSession( protocol::Session* session, protocol::SessionManager::IncomingSessionResponse* response); // Sets desired configuration for the protocol. Ownership of the // |config| is transferred to the object. Must be called before Start(). void set_protocol_config(protocol::CandidateSessionConfig* config); // TODO(wez): ChromotingHost shouldn't need to know about Me2Mom. void set_it2me(bool is_it2me) { is_it2me_ = is_it2me; } // Notify all active client sessions that local input has been detected, and // that remote input should be ignored for a short time. void LocalMouseMoved(const gfx::Point& new_pos); // Pause or unpause the session. While the session is paused, remote input // is ignored. void PauseSession(bool pause); private: friend class base::RefCountedThreadSafe<ChromotingHost>; friend class ChromotingHostTest; typedef std::vector<HostStatusObserver*> StatusObserverList; typedef std::vector<scoped_refptr<ClientSession> > ClientList; // Takes ownership of |access_verifier| and |environment|, and adds a // reference to |config|. Does NOT take ownership of |context|. ChromotingHost(ChromotingHostContext* context, MutableHostConfig* config, DesktopEnvironment* environment, AccessVerifier* access_verifier); virtual ~ChromotingHost(); enum State { kInitial, kStarted, kStopping, kStopped, }; // This method is called if a client is disconnected from the host. void OnClientDisconnected(protocol::ConnectionToClient* client); // Creates encoder for the specified configuration. Encoder* CreateEncoder(const protocol::SessionConfig* config); std::string GenerateHostAuthToken(const std::string& encoded_client_token); int AuthenticatedClientsCount() const; void EnableCurtainMode(bool enable); void MonitorLocalInputs(bool enable); void ProcessPreAuthentication( const scoped_refptr<protocol::ConnectionToClient>& connection); // Show or hide the Disconnect window on the UI thread. If |show| is false, // hide the window, ignoring the |username| parameter. void ShowDisconnectWindow(bool show, const std::string& username); // Show or hide the Continue Sharing window on the UI thread. void ShowContinueWindow(bool show); void StartContinueWindowTimer(bool start); void ContinueWindowTimerFunc(); // The following methods are called during shutdown. void ShutdownJingleClient(); void ShutdownSignallingDisconnected(); void ShutdownRecorder(); void ShutdownFinish(); // The context that the chromoting host runs on. ChromotingHostContext* context_; scoped_refptr<MutableHostConfig> config_; scoped_ptr<DesktopEnvironment> desktop_environment_; scoped_ptr<SignalStrategy> signal_strategy_; // The libjingle client. This is used to connect to the talk network to // receive connection requests from chromoting client. scoped_refptr<JingleClient> jingle_client_; scoped_refptr<protocol::SessionManager> session_manager_; StatusObserverList status_observers_; scoped_ptr<AccessVerifier> access_verifier_; // The connections to remote clients. ClientList clients_; // Session manager for the host process. scoped_refptr<ScreenRecorder> recorder_; // Tracks the internal state of the host. // This variable is written on the main thread of ChromotingHostContext // and read by jingle thread. State state_; // Lock is to lock the access to |state_|. base::Lock lock_; // Configuration of the protocol. scoped_ptr<protocol::CandidateSessionConfig> protocol_config_; bool is_curtained_; bool is_monitoring_local_inputs_; // Timer controlling the "continue session" dialog. The timer is started when // a connection is made or re-confirmed. On expiry, inputs to the host are // blocked and the dialog is shown. base::OneShotTimer<ChromotingHost> continue_window_timer_; // Whether or not the host is running in "IT2Me" mode, in which connections // are pre-authenticated, and hence the local login challenge can be bypassed. bool is_it2me_; // Stores list of tasks that should be executed when we finish // shutdown. Used only while |state_| is set to kStopping. std::vector<Task*> shutdown_tasks_; DISALLOW_COPY_AND_ASSIGN(ChromotingHost); }; } // namespace remoting #endif // REMOTING_HOST_CHROMOTING_HOST_H_