// Copyright (c) 2012 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_CHROMOTING_HOST_H_
#define REMOTING_HOST_CHROMOTING_HOST_H_
#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/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"
#include "remoting/protocol/connection_to_client.h"
#include "remoting/protocol/pairing_registry.h"
#include "remoting/protocol/session_manager.h"
namespace base {
class SingleThreadTaskRunner;
} // namespace base
namespace remoting {
namespace protocol {
class InputStub;
class SessionConfig;
class CandidateSessionConfig;
} // namespace protocol
class DesktopEnvironmentFactory;
// 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 VideoScheduler is created with an Encoder and a webrtc::DesktopCapturer.
// 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::NonThreadSafe,
public ClientSession::EventHandler,
public protocol::SessionManager::Listener,
public HostStatusMonitor {
public:
// Both |signal_strategy| and |desktop_environment_factory| should outlive
// this object.
ChromotingHost(
SignalStrategy* signal_strategy,
DesktopEnvironmentFactory* desktop_environment_factory,
scoped_ptr<protocol::SessionManager> session_manager,
scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> video_encode_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> network_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner);
virtual ~ChromotingHost();
// Asynchronously starts the host.
//
// 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(const std::string& host_owner);
// HostStatusMonitor interface.
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.
void RejectAuthenticatingClient();
// Sets the authenticator factory to use for incoming
// connections. Incoming connections are rejected until
// authenticator factory is set. Must be called on the network
// thread after the host is started. Must not be called more than
// once per host instance because it may not be safe to delete
// factory before all authenticators it created are deleted.
void SetAuthenticatorFactory(
scoped_ptr<protocol::AuthenticatorFactory> authenticator_factory);
// Enables/disables curtaining when one or more clients are connected.
// Takes immediate effect if clients are already connected.
void SetEnableCurtaining(bool enable);
// Sets the maximum duration of any session. By default, a session has no
// maximum duration.
void SetMaximumSessionDuration(const base::TimeDelta& max_session_duration);
////////////////////////////////////////////////////////////////////////////
// ClientSession::EventHandler implementation.
virtual void OnSessionAuthenticating(ClientSession* client) OVERRIDE;
virtual bool OnSessionAuthenticated(ClientSession* client) OVERRIDE;
virtual void OnSessionChannelsConnected(ClientSession* client) OVERRIDE;
virtual void OnSessionAuthenticationFailed(ClientSession* client) OVERRIDE;
virtual void OnSessionClosed(ClientSession* session) OVERRIDE;
virtual void OnSessionRouteChange(
ClientSession* session,
const std::string& channel_name,
const protocol::TransportRoute& route) OVERRIDE;
// SessionManager::Listener implementation.
virtual void OnSessionManagerReady() OVERRIDE;
virtual void OnIncomingSession(
protocol::Session* session,
protocol::SessionManager::IncomingSessionResponse* response) OVERRIDE;
// Gets the candidate configuration for the protocol.
const protocol::CandidateSessionConfig* protocol_config() const {
return protocol_config_.get();
}
// Sets desired configuration for the protocol. Must be called before Start().
void set_protocol_config(scoped_ptr<protocol::CandidateSessionConfig> config);
// The host uses a pairing registry to generate and store pairing information
// for clients for PIN-less authentication.
scoped_refptr<protocol::PairingRegistry> pairing_registry() const {
return pairing_registry_;
}
void set_pairing_registry(
scoped_refptr<protocol::PairingRegistry> pairing_registry) {
pairing_registry_ = pairing_registry;
}
base::WeakPtr<ChromotingHost> AsWeakPtr() {
return weak_factory_.GetWeakPtr();
}
private:
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
// callbacks for disconnected clients after this call returns.
void DisconnectAllClients();
// Unless specified otherwise all members of this class must be
// used on the network thread only.
// Parameters specified when the host was created.
DesktopEnvironmentFactory* desktop_environment_factory_;
scoped_ptr<protocol::SessionManager> session_manager_;
scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> input_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> video_encode_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
// Connection objects.
SignalStrategy* signal_strategy_;
// Must be used on the network thread only.
ObserverList<HostStatusObserver> status_observers_;
// The connections to remote clients.
ClientList clients_;
// True if the host has been started.
bool started_;
// Configuration of the protocol.
scoped_ptr<protocol::CandidateSessionConfig> protocol_config_;
// Login backoff state.
net::BackoffEntry login_backoff_;
// Flags used for RejectAuthenticatingClient().
bool authenticating_client_;
bool reject_authenticating_client_;
// True if the curtain mode is enabled.
bool enable_curtaining_;
// The maximum duration of any session.
base::TimeDelta max_session_duration_;
// 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);
};
} // namespace remoting
#endif // REMOTING_HOST_CHROMOTING_HOST_H_