#ifndef REMOTING_HOST_CLIENT_SESSION_H_
#define REMOTING_HOST_CLIENT_SESSION_H_
#include <cstdint>
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include "base/callback_list.h"
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "build/build_config.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "remoting/base/constants.h"
#include "remoting/base/errors.h"
#include "remoting/base/local_session_policies_provider.h"
#include "remoting/base/session_policies.h"
#include "remoting/host/base/desktop_environment_options.h"
#include "remoting/host/client_session_control.h"
#include "remoting/host/client_session_details.h"
#include "remoting/host/client_session_events.h"
#include "remoting/host/cursor_visibility_notifier.h"
#include "remoting/host/desktop_display_info.h"
#include "remoting/host/host_experiment_session_plugin.h"
#include "remoting/host/host_extension_session_manager.h"
#include "remoting/host/mojom/chromoting_host_services.mojom.h"
#include "remoting/host/mojom/remote_url_opener.mojom.h"
#include "remoting/host/mojom/webauthn_proxy.mojom.h"
#include "remoting/host/remote_input_filter.h"
#include "remoting/proto/action.pb.h"
#include "remoting/protocol/clipboard_echo_filter.h"
#include "remoting/protocol/clipboard_filter.h"
#include "remoting/protocol/clipboard_stub.h"
#include "remoting/protocol/connection_to_client.h"
#include "remoting/protocol/coordinate_converter.h"
#include "remoting/protocol/data_channel_manager.h"
#include "remoting/protocol/display_size.h"
#include "remoting/protocol/errors.h"
#include "remoting/protocol/fractional_input_filter.h"
#include "remoting/protocol/host_stub.h"
#include "remoting/protocol/input_event_timestamps.h"
#include "remoting/protocol/input_event_tracker.h"
#include "remoting/protocol/input_filter.h"
#include "remoting/protocol/mouse_cursor_monitor.h"
#include "remoting/protocol/mouse_input_filter.h"
#include "remoting/protocol/observing_input_filter.h"
#include "remoting/protocol/pairing_registry.h"
#include "remoting/protocol/transport.h"
#include "remoting/protocol/video_stream.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_capture_types.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
#include "third_party/webrtc/modules/desktop_capture/mouse_cursor.h"
#include "ui/events/types/event_type.h"
namespace remoting {
class ActiveDisplayMonitor;
class DesktopEnvironment;
class DesktopEnvironmentFactory;
class InputInjector;
class KeyboardLayoutMonitor;
class MouseShapePump;
class RemoteOpenUrlMessageHandler;
class RemoteWebAuthnMessageHandler;
class ScreenControls;
namespace protocol {
class AudioStream;
class VideoLayout;
}
class ClientSession : public protocol::HostStub,
public protocol::ConnectionToClient::EventHandler,
public protocol::VideoStream::Observer,
public ClientSessionControl,
public ClientSessionDetails,
public ClientSessionEvents,
public CursorVisibilityNotifier::EventHandler,
public protocol::MouseCursorMonitor::Callback,
public mojom::ChromotingSessionServices {
public:
class EventHandler {
public:
virtual void OnSessionAuthenticating(ClientSession* client) = 0;
virtual void OnSessionAuthenticated(ClientSession* client) = 0;
virtual void OnSessionChannelsConnected(ClientSession* client) = 0;
virtual void OnSessionAuthenticationFailed(ClientSession* client) = 0;
virtual void OnSessionClosed(ClientSession* client) = 0;
virtual void OnSessionRouteChange(
ClientSession* client,
const std::string& channel_name,
const protocol::TransportRoute& route) = 0;
virtual std::optional<ErrorCode> OnSessionPoliciesReceived(
const SessionPolicies& policies) = 0;
protected:
virtual ~EventHandler() {}
};
ClientSession(
EventHandler* event_handler,
std::unique_ptr<protocol::ConnectionToClient> connection,
DesktopEnvironmentFactory* desktop_environment_factory,
const DesktopEnvironmentOptions& desktop_environment_options,
scoped_refptr<protocol::PairingRegistry> pairing_registry,
const std::vector<raw_ptr<HostExtension, VectorExperimental>>& extensions,
const LocalSessionPoliciesProvider* local_session_policies_provider);
ClientSession(const ClientSession&) = delete;
ClientSession& operator=(const ClientSession&) = delete;
~ClientSession() override;
const std::string& capabilities() const { return capabilities_; }
void NotifyClientResolution(
const protocol::ClientResolution& resolution) override;
void ControlVideo(const protocol::VideoControl& video_control) override;
void ControlAudio(const protocol::AudioControl& audio_control) override;
void SetCapabilities(const protocol::Capabilities& capabilities) override;
void RequestPairing(
const remoting::protocol::PairingRequest& pairing_request) override;
void DeliverClientMessage(const protocol::ExtensionMessage& message) override;
void SelectDesktopDisplay(
const protocol::SelectDesktopDisplayRequest& select_display) override;
void ControlPeerConnection(
const protocol::PeerConnectionParameters& parameters) override;
void SetVideoLayout(const protocol::VideoLayout& video_layout) override;
void OnConnectionAuthenticating() override;
void OnConnectionAuthenticated(
const SessionPolicies* session_policies) override;
void CreateMediaStreams() override;
void OnConnectionChannelsConnected() override;
void OnConnectionClosed(protocol::ErrorCode error) override;
void OnTransportProtocolChange(const std::string& protocol) override;
void OnRouteChange(const std::string& channel_name,
const protocol::TransportRoute& route) override;
void OnIncomingDataChannel(
const std::string& channel_name,
std::unique_ptr<protocol::MessagePipe> pipe) override;
const std::string& client_jid() const override;
void DisconnectSession(ErrorCode error,
std::string_view error_details,
const SourceLocation& error_location) override;
void OnLocalKeyPressed(std::uint32_t usb_keycode) override;
void OnLocalPointerMoved(const webrtc::DesktopVector& position,
ui::EventType type) override;
void SetDisableInputs(bool disable_inputs) override;
void OnDesktopDisplayChanged(
std::unique_ptr<protocol::VideoLayout> layout) override;
void OnDesktopAttached(std::uint32_t session_id) override;
void OnDesktopDetached() override;
std::uint32_t desktop_session_id() const override;
ClientSessionControl* session_control() override;
void OnCursorVisibilityChanged(bool visible) override;
void OnMouseCursor(
std::unique_ptr<webrtc::MouseCursor> mouse_cursor) override;
void OnMouseCursorPosition(const webrtc::DesktopVector& position) override;
void BindWebAuthnProxy(
mojo::PendingReceiver<mojom::WebAuthnProxy> receiver) override;
void BindRemoteUrlOpener(
mojo::PendingReceiver<mojom::RemoteUrlOpener> receiver) override;
#if BUILDFLAG(IS_WIN)
void BindSecurityKeyForwarder(
mojo::PendingReceiver<mojom::SecurityKeyForwarder> receiver) override;
#endif
void BindReceiver(
mojo::PendingReceiver<mojom::ChromotingSessionServices> receiver);
protocol::ConnectionToClient* connection() const { return connection_.get(); }
bool is_authenticated() const { return is_authenticated_; }
bool channels_connected() const { return channels_connected_; }
const std::string* client_capabilities() const {
return client_capabilities_.get();
}
void RegisterCreateHandlerCallbackForTesting(
const std::string& prefix,
protocol::DataChannelManager::CreateHandlerCallback constructor);
void SetEventTimestampsSourceForTests(
scoped_refptr<protocol::InputEventTimestampsSource>
event_timestamp_source);
void UpdateMouseClampingFilterOffset();
const SessionPolicies& effective_policies_for_tests() const {
return effective_policies_;
}
private:
void OnDesktopEnvironmentCreated(
std::unique_ptr<DesktopEnvironment> desktop_environment);
void OnLocalSessionPoliciesChanged(const SessionPolicies& new_policies);
std::unique_ptr<protocol::ClipboardStub> CreateClipboardProxy();
void SetMouseClampingFilter(const DisplaySize& size);
void OnVideoSizeChanged(protocol::VideoStream* stream,
const webrtc::DesktopSize& size,
const webrtc::DesktopVector& dpi) override;
void CreateActionMessageHandler(
std::vector<protocol::ActionRequest::Action> capabilities,
const std::string& channel_name,
std::unique_ptr<protocol::MessagePipe> pipe);
void CreateFileTransferMessageHandler(
const std::string& channel_name,
std::unique_ptr<protocol::MessagePipe> pipe);
void CreateRtcLogTransferMessageHandler(
const std::string& channel_name,
std::unique_ptr<protocol::MessagePipe> pipe);
void CreateRemoteOpenUrlMessageHandler(
const std::string& channel_name,
std::unique_ptr<protocol::MessagePipe> pipe);
void CreateUrlForwarderControlMessageHandler(
const std::string& channel_name,
std::unique_ptr<protocol::MessagePipe> pipe);
void CreateRemoteWebAuthnMessageHandler(
const std::string& channel_name,
std::unique_ptr<protocol::MessagePipe> pipe);
void CreatePerMonitorVideoStreams();
bool IsValidDisplayIndex(webrtc::ScreenId index) const;
void BoostFramerateOnInput(base::TimeDelta capture_interval,
base::TimeDelta boost_duration,
bool& mouse_button_down,
protocol::ObservingInputFilter::Event event);
void OnActiveDisplayChanged(webrtc::ScreenId display);
void UpdateCoordinateConverterFallback();
void SetComposeEnabledOnVideoStreams(bool enabled);
raw_ptr<EventHandler> event_handler_;
raw_ptr<DesktopEnvironmentFactory> desktop_environment_factory_;
DesktopEnvironmentOptions desktop_environment_options_;
std::unique_ptr<DesktopEnvironment> desktop_environment_;
std::vector<base::OnceClosure> desktop_environment_ready_callbacks_;
protocol::CoordinateConverter coordinate_converter_;
protocol::InputEventTracker input_tracker_;
CursorVisibilityNotifier cursor_visibility_notifier_;
RemoteInputFilter remote_input_filter_;
protocol::FractionalInputFilter fractional_input_filter_;
protocol::MouseInputFilter mouse_clamping_filter_;
protocol::ObservingInputFilter observing_input_filter_;
protocol::ClipboardEchoFilter clipboard_echo_filter_;
protocol::InputFilter disable_input_filter_;
protocol::ClipboardFilter host_clipboard_filter_;
protocol::ClipboardFilter client_clipboard_filter_;
base::WeakPtrFactory<protocol::ClipboardStub> client_clipboard_factory_;
base::OneShotTimer max_duration_timer_;
std::map<webrtc::ScreenId, std::unique_ptr<protocol::VideoStream>>
video_streams_;
std::unique_ptr<protocol::AudioStream> audio_stream_;
std::unique_ptr<std::string> client_capabilities_;
std::string host_capabilities_;
std::string capabilities_;
std::unique_ptr<InputInjector> input_injector_;
std::unique_ptr<ScreenControls> screen_controls_;
DesktopDisplayInfo desktop_display_info_;
int default_x_dpi_ = kDefaultDpi;
int default_y_dpi_ = kDefaultDpi;
webrtc::ScreenId selected_display_index_ = webrtc::kInvalidScreenId;
DisplaySize default_webrtc_desktop_size_;
DisplaySize webrtc_capture_size_;
bool can_capture_full_desktop_ = true;
scoped_refptr<protocol::PairingRegistry> pairing_registry_;
protocol::DataChannelManager data_channel_manager_;
bool is_authenticated_ = false;
bool channels_connected_ = false;
bool pause_video_ = false;
int target_framerate_ = kTargetFrameRate;
std::unique_ptr<protocol::VideoLayout> pending_video_layout_message_;
scoped_refptr<protocol::InputEventTimestampsSource>
event_timestamp_source_for_tests_;
HostExperimentSessionPlugin host_experiment_session_plugin_;
std::unique_ptr<protocol::ConnectionToClient> connection_;
std::string client_jid_;
std::unique_ptr<HostExtensionSessionManager> extension_manager_;
std::unique_ptr<MouseShapePump> mouse_shape_pump_;
std::unique_ptr<KeyboardLayoutMonitor> keyboard_layout_monitor_;
base::WeakPtr<RemoteWebAuthnMessageHandler> remote_webauthn_message_handler_;
base::WeakPtr<RemoteOpenUrlMessageHandler> remote_open_url_message_handler_;
mojo::ReceiverSet<mojom::ChromotingSessionServices>
session_services_receivers_;
std::unique_ptr<ActiveDisplayMonitor> active_display_monitor_;
SessionPolicies effective_policies_;
raw_ptr<const LocalSessionPoliciesProvider> local_session_policies_provider_;
base::CallbackListSubscription local_session_policy_update_subscription_;
bool host_cursor_rendered_by_client_ = false;
bool cursor_visible_ = false;
SEQUENCE_CHECKER(sequence_checker_);
base::WeakPtrFactory<ClientSession> weak_factory_{this};
};
}
#endif