#ifndef REMOTING_HOST_DESKTOP_SESSION_AGENT_H_
#define REMOTING_HOST_DESKTOP_SESSION_AGENT_H_
#include <stddef.h>
#include <stdint.h>
#include <map>
#include <memory>
#include "base/compiler_specific.h"
#include "base/functional/callback.h"
#include "base/memory/read_only_shared_memory_region.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.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/bindings/scoped_interface_endpoint_handle.h"
#include "mojo/public/cpp/system/message_pipe.h"
#include "remoting/host/base/desktop_environment_options.h"
#include "remoting/host/client_session_control.h"
#include "remoting/host/desktop_display_info.h"
#include "remoting/host/file_transfer/session_file_operations_handler.h"
#include "remoting/host/mojom/desktop_session.mojom.h"
#include "remoting/host/mojom/remoting_mojom_traits.h"
#include "remoting/proto/url_forwarder_control.pb.h"
#include "remoting/protocol/clipboard_stub.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
#include "third_party/webrtc/modules/desktop_capture/mouse_cursor_monitor.h"
#include "ui/events/event.h"
namespace base {
class Location;
}
namespace IPC {
class ChannelProxy;
class Message;
}
namespace remoting {
class ActionExecutor;
class AudioCapturer;
class AudioPacket;
class AutoThreadTaskRunner;
class DesktopCapturer;
class DesktopEnvironment;
class DesktopEnvironmentFactory;
class InputInjector;
class KeyboardLayoutMonitor;
class RemoteInputFilter;
class RemoteWebAuthnStateChangeNotifier;
class ScreenControls;
class ScreenResolution;
class UrlForwarderConfigurator;
namespace protocol {
class InputEventTracker;
}
class DesktopSessionAgent
: public base::RefCountedThreadSafe<DesktopSessionAgent>,
public IPC::Listener,
public webrtc::DesktopCapturer::Callback,
public webrtc::MouseCursorMonitor::Callback,
public ClientSessionControl,
public mojom::DesktopSessionAgent,
public mojom::DesktopSessionControl {
public:
class Delegate {
public:
virtual ~Delegate();
virtual DesktopEnvironmentFactory& desktop_environment_factory() = 0;
virtual void OnNetworkProcessDisconnected() = 0;
virtual void CrashNetworkProcess(const base::Location& location) = 0;
};
DesktopSessionAgent(
scoped_refptr<AutoThreadTaskRunner> audio_capture_task_runner,
scoped_refptr<AutoThreadTaskRunner> caller_task_runner,
scoped_refptr<AutoThreadTaskRunner> input_task_runner,
scoped_refptr<AutoThreadTaskRunner> io_task_runner);
DesktopSessionAgent(const DesktopSessionAgent&) = delete;
DesktopSessionAgent& operator=(const DesktopSessionAgent&) = delete;
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;
void OnCaptureResult(webrtc::DesktopCapturer::Result result,
std::unique_ptr<webrtc::DesktopFrame> frame) override;
void OnMouseCursor(webrtc::MouseCursor* cursor) override;
void OnMouseCursorPosition(const webrtc::DesktopVector& position) override;
void OnClipboardEvent(const protocol::ClipboardEvent& event);
void ProcessAudioPacket(std::unique_ptr<AudioPacket> packet);
void Start(const std::string& authenticated_jid,
const ScreenResolution& resolution,
const DesktopEnvironmentOptions& options,
StartCallback callback) override;
void CaptureFrame() override;
void SelectSource(int id) override;
void SetScreenResolution(const ScreenResolution& resolution) override;
void LockWorkstation() override;
void InjectSendAttentionSequence() override;
void InjectClipboardEvent(const protocol::ClipboardEvent& event) override;
void InjectKeyEvent(const protocol::KeyEvent& event) override;
void InjectMouseEvent(const protocol::MouseEvent& event) override;
void InjectTextEvent(const protocol::TextEvent& event) override;
void InjectTouchEvent(const protocol::TouchEvent& event) override;
void SetUpUrlForwarder() override;
void SignalWebAuthnExtension() override;
void BeginFileRead(BeginFileReadCallback callback) override;
void BeginFileWrite(const base::FilePath& file_path,
BeginFileWriteCallback callback) override;
mojo::ScopedMessagePipeHandle Initialize(
const base::WeakPtr<Delegate>& delegate);
void Stop();
protected:
friend class base::RefCountedThreadSafe<DesktopSessionAgent>;
~DesktopSessionAgent() override;
const std::string& client_jid() const override;
void DisconnectSession(protocol::ErrorCode error) override;
void OnLocalKeyPressed(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 OnKeyboardLayoutChange(const protocol::KeyboardLayout& layout);
void OnSharedMemoryRegionCreated(int id,
base::ReadOnlySharedMemoryRegion region,
uint32_t size);
void OnSharedMemoryRegionReleased(int id);
void StartAudioCapturer();
void StopAudioCapturer();
private:
void OnCheckUrlForwarderSetUpResult(bool is_set_up);
void OnUrlForwarderSetUpStateChanged(
protocol::UrlForwarderControl::SetUpUrlForwarderResponse::State state);
scoped_refptr<AutoThreadTaskRunner> audio_capture_task_runner_;
scoped_refptr<AutoThreadTaskRunner> caller_task_runner_;
scoped_refptr<AutoThreadTaskRunner> input_task_runner_;
scoped_refptr<AutoThreadTaskRunner> io_task_runner_;
std::unique_ptr<AudioCapturer> audio_capturer_;
std::string client_jid_;
base::WeakPtr<Delegate> delegate_;
std::unique_ptr<DesktopEnvironment> desktop_environment_;
std::unique_ptr<ActionExecutor> action_executor_;
std::unique_ptr<InputInjector> input_injector_;
std::unique_ptr<protocol::InputEventTracker> input_tracker_;
std::unique_ptr<RemoteInputFilter> remote_input_filter_;
std::unique_ptr<ScreenControls> screen_controls_;
std::unique_ptr<IPC::ChannelProxy> network_channel_;
bool started_ = false;
std::unique_ptr<DesktopCapturer> video_capturer_;
std::unique_ptr<webrtc::MouseCursorMonitor> mouse_cursor_monitor_;
std::unique_ptr<KeyboardLayoutMonitor> keyboard_layout_monitor_;
std::unique_ptr<webrtc::DesktopFrame> last_frame_;
absl::optional<SessionFileOperationsHandler> session_file_operations_handler_;
mojo::AssociatedRemote<mojom::DesktopSessionEventHandler>
desktop_session_event_handler_;
mojo::AssociatedRemote<mojom::DesktopSessionStateHandler>
desktop_session_state_handler_;
mojo::AssociatedReceiver<mojom::DesktopSessionAgent> desktop_session_agent_{
this};
mojo::AssociatedReceiver<mojom::DesktopSessionControl>
desktop_session_control_{this};
std::unique_ptr<::remoting::UrlForwarderConfigurator>
url_forwarder_configurator_;
std::unique_ptr<RemoteWebAuthnStateChangeNotifier>
webauthn_state_change_notifier_;
base::WeakPtrFactory<DesktopSessionAgent> weak_factory_{this};
};
}
#endif