#ifndef REMOTING_HOST_DESKTOP_SESSION_PROXY_H_
#define REMOTING_HOST_DESKTOP_SESSION_PROXY_H_
#include <cstdint>
#include <map>
#include <memory>
#include <optional>
#include <vector>
#include "base/callback_list.h"
#include "base/functional/callback.h"
#include "base/memory/read_only_shared_memory_region.h"
#include "base/memory/ref_counted_delete_on_sequence.h"
#include "base/memory/weak_ptr.h"
#include "base/process/process.h"
#include "base/sequence_checker.h"
#include "base/task/sequenced_task_runner_helpers.h"
#include "ipc/ipc_listener.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
#include "mojo/public/cpp/system/message_pipe.h"
#include "remoting/host/action_executor.h"
#include "remoting/host/audio_capturer.h"
#include "remoting/host/base/screen_resolution.h"
#include "remoting/host/desktop_environment.h"
#include "remoting/host/file_transfer/ipc_file_operations.h"
#include "remoting/host/mojom/desktop_session.mojom.h"
#include "remoting/host/mojom/remoting_mojom_traits.h"
#include "remoting/host/remote_open_url/url_forwarder_configurator.h"
#include "remoting/host/webauthn/remote_webauthn_state_change_notifier.h"
#include "remoting/proto/control.pb.h"
#include "remoting/proto/event.pb.h"
#include "remoting/proto/url_forwarder_control.pb.h"
#include "remoting/protocol/clipboard_stub.h"
#include "remoting/protocol/desktop_capturer.h"
#include "remoting/protocol/errors.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_capture_types.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
namespace base {
class SingleThreadTaskRunner;
}
namespace IPC {
class ChannelProxy;
class Message;
}
namespace webrtc {
class MouseCursor;
}
namespace remoting {
class AudioPacket;
class ClientSessionControl;
class DesktopSessionConnector;
class IpcAudioCapturer;
class IpcMouseCursorMonitor;
class IpcKeyboardLayoutMonitor;
class IpcVideoFrameCapturer;
class ScreenControls;
class DesktopSessionProxy
: public base::RefCountedDeleteOnSequence<DesktopSessionProxy>,
public IPC::Listener,
public IpcFileOperations::RequestHandler,
public mojom::DesktopSessionEventHandler,
public mojom::DesktopSessionStateHandler {
public:
DesktopSessionProxy(
scoped_refptr<base::SingleThreadTaskRunner> audio_capture_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
base::WeakPtr<ClientSessionControl> client_session_control,
base::WeakPtr<ClientSessionEvents> client_session_events,
base::WeakPtr<DesktopSessionConnector> desktop_session_connector,
const DesktopEnvironmentOptions& options);
DesktopSessionProxy(const DesktopSessionProxy&) = delete;
DesktopSessionProxy& operator=(const DesktopSessionProxy&) = delete;
std::unique_ptr<ActionExecutor> CreateActionExecutor();
std::unique_ptr<AudioCapturer> CreateAudioCapturer();
std::unique_ptr<InputInjector> CreateInputInjector();
std::unique_ptr<ScreenControls> CreateScreenControls();
std::unique_ptr<DesktopCapturer> CreateVideoCapturer(webrtc::ScreenId id);
std::unique_ptr<webrtc::MouseCursorMonitor> CreateMouseCursorMonitor();
std::unique_ptr<KeyboardLayoutMonitor> CreateKeyboardLayoutMonitor(
base::RepeatingCallback<void(const protocol::KeyboardLayout&)> callback);
std::unique_ptr<FileOperations> CreateFileOperations();
std::unique_ptr<UrlForwarderConfigurator> CreateUrlForwarderConfigurator();
std::unique_ptr<RemoteWebAuthnStateChangeNotifier>
CreateRemoteWebAuthnStateChangeNotifier();
std::string GetCapabilities() const;
void SetCapabilities(const std::string& capabilities);
bool OnMessageReceived(const IPC::Message& message) override;
void OnChannelConnected(int32_t peer_pid) override;
void OnChannelError() override;
void OnAssociatedInterfaceRequest(
const std::string& interface_name,
mojo::ScopedInterfaceEndpointHandle handle) override;
bool AttachToDesktop(mojo::ScopedMessagePipeHandle desktop_pipe,
int session_id);
void DetachFromDesktop();
void SetAudioCapturer(const base::WeakPtr<IpcAudioCapturer>& audio_capturer);
void SetMouseCursorMonitor(
const base::WeakPtr<IpcMouseCursorMonitor>& mouse_cursor_monitor);
void SetKeyboardLayoutMonitor(
const base::WeakPtr<IpcKeyboardLayoutMonitor>& keyboard_layout_monitor);
const std::optional<protocol::KeyboardLayout>& GetKeyboardCurrentLayout()
const;
void RebindSingleVideoCapturer(
webrtc::ScreenId new_id,
base::WeakPtr<IpcVideoFrameCapturer> capturer_weakptr);
void InjectClipboardEvent(const protocol::ClipboardEvent& event);
void InjectKeyEvent(const protocol::KeyEvent& event);
void InjectTextEvent(const protocol::TextEvent& event);
void InjectMouseEvent(const protocol::MouseEvent& event);
void InjectTouchEvent(const protocol::TouchEvent& event);
void StartInputInjector(
std::unique_ptr<protocol::ClipboardStub> client_clipboard);
void SetScreenResolution(const ScreenResolution& resolution);
void ExecuteAction(const protocol::ActionRequest& request);
void BeginFileRead(IpcFileOperations::BeginFileReadCallback callback,
base::OnceClosure on_disconnect) override;
void BeginFileWrite(const base::FilePath& file_path,
IpcFileOperations::BeginFileWriteCallback callback,
base::OnceClosure on_disconnect) override;
void OnClipboardEvent(const protocol::ClipboardEvent& event) override;
void OnUrlForwarderStateChange(mojom::UrlForwarderState state) override;
void OnAudioPacket(std::unique_ptr<AudioPacket> audio_packet) override;
void OnDesktopDisplayChanged(const protocol::VideoLayout& layout) override;
void OnMouseCursorChanged(const webrtc::MouseCursor& mouse_cursor) override;
void OnKeyboardLayoutChanged(const protocol::KeyboardLayout& layout) override;
void OnLocalMouseMoveDetected(
const webrtc::DesktopVector& new_position) override;
void OnLocalKeyboardInputDetected(int32_t usb_keycode) override;
void DisconnectSession(protocol::ErrorCode error,
const std::string& error_details,
const SourceLocation& error_location) override;
void IsUrlForwarderSetUp(
UrlForwarderConfigurator::IsUrlForwarderSetUpCallback callback);
void SetUpUrlForwarder(
const UrlForwarderConfigurator::SetUpUrlForwarderCallback& callback);
uint32_t desktop_session_id() const { return desktop_session_id_; }
private:
friend class base::RefCountedDeleteOnSequence<DesktopSessionProxy>;
friend class base::DeleteHelper<DesktopSessionProxy>;
~DesktopSessionProxy() override;
void OnDesktopSessionAgentStarted(
mojo::PendingAssociatedRemote<mojom::DesktopSessionControl>
pending_remote);
void OnBeginFileReadResult(
IpcFileOperations::BeginFileReadCallback callback,
base::CallbackListSubscription disconnect_handler_subscription,
mojom::BeginFileReadResultPtr result);
void OnBeginFileWriteResult(
IpcFileOperations::BeginFileWriteCallback callback,
base::CallbackListSubscription disconnect_handler_subscription,
mojom::BeginFileWriteResultPtr result);
void SignalWebAuthnExtension();
void RequestMojoVideoCapturer(webrtc::ScreenId id,
base::WeakPtr<IpcVideoFrameCapturer> capturer);
scoped_refptr<base::SingleThreadTaskRunner> audio_capture_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner_;
base::WeakPtr<IpcAudioCapturer> audio_capturer_;
std::unique_ptr<protocol::ClipboardStub> client_clipboard_
GUARDED_BY_CONTEXT(sequence_checker_);
base::WeakPtr<ClientSessionControl> client_session_control_
GUARDED_BY_CONTEXT(sequence_checker_);
base::WeakPtr<ClientSessionEvents> client_session_events_
GUARDED_BY_CONTEXT(sequence_checker_);
base::WeakPtr<DesktopSessionConnector> desktop_session_connector_
GUARDED_BY_CONTEXT(sequence_checker_);
std::map<webrtc::ScreenId, base::WeakPtr<IpcVideoFrameCapturer>>
video_capturers_ GUARDED_BY_CONTEXT(sequence_checker_);
base::WeakPtr<IpcMouseCursorMonitor> mouse_cursor_monitor_
GUARDED_BY_CONTEXT(sequence_checker_);
base::WeakPtr<IpcKeyboardLayoutMonitor> keyboard_layout_monitor_
GUARDED_BY_CONTEXT(sequence_checker_);
IpcFileOperationsFactory ipc_file_operations_factory_
GUARDED_BY_CONTEXT(sequence_checker_);
std::unique_ptr<IPC::ChannelProxy> desktop_channel_
GUARDED_BY_CONTEXT(sequence_checker_);
ScreenResolution screen_resolution_ GUARDED_BY_CONTEXT(sequence_checker_);
bool is_desktop_session_connected_ GUARDED_BY_CONTEXT(sequence_checker_);
DesktopEnvironmentOptions options_ GUARDED_BY_CONTEXT(sequence_checker_);
uint32_t desktop_session_id_ = UINT32_MAX;
std::optional<protocol::KeyboardLayout> keyboard_layout_
GUARDED_BY_CONTEXT(sequence_checker_);
base::OnceClosureList disconnect_handlers_
GUARDED_BY_CONTEXT(sequence_checker_);
mojo::AssociatedRemote<mojom::DesktopSessionAgent> desktop_session_agent_
GUARDED_BY_CONTEXT(sequence_checker_);
mojo::AssociatedRemote<mojom::DesktopSessionControl> desktop_session_control_
GUARDED_BY_CONTEXT(sequence_checker_);
mojo::AssociatedReceiver<mojom::DesktopSessionEventHandler>
desktop_session_event_handler_ GUARDED_BY_CONTEXT(sequence_checker_){
this};
mojo::AssociatedReceiver<mojom::DesktopSessionStateHandler>
desktop_session_state_handler_ GUARDED_BY_CONTEXT(sequence_checker_){
this};
UrlForwarderConfigurator::IsUrlForwarderSetUpCallback
is_url_forwarder_set_up_callback_ GUARDED_BY_CONTEXT(sequence_checker_);
UrlForwarderConfigurator::SetUpUrlForwarderCallback
set_up_url_forwarder_callback_ GUARDED_BY_CONTEXT(sequence_checker_);
mojom::UrlForwarderState current_url_forwarder_state_ GUARDED_BY_CONTEXT(
sequence_checker_) = mojom::UrlForwarderState::kUnknown;
SEQUENCE_CHECKER(sequence_checker_);
};
}
#endif