| // Copyright 2026 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef REMOTING_HOST_IPC_PEER_SESSION_H_ |
| #define REMOTING_HOST_IPC_PEER_SESSION_H_ |
| |
| #include <memory> |
| #include <string> |
| #include <string_view> |
| #include <vector> |
| |
| #include "base/functional/callback.h" |
| #include "base/functional/callback_helpers.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/sequence_checker.h" |
| #include "mojo/public/cpp/bindings/associated_remote.h" |
| #include "mojo/public/cpp/bindings/pending_associated_remote.h" |
| #include "mojo/public/cpp/bindings/pending_remote.h" |
| #include "mojo/public/cpp/bindings/receiver.h" |
| #include "mojo/public/cpp/bindings/remote.h" |
| #include "remoting/host/mojom/desktop_session.mojom.h" |
| #include "remoting/host/mojom/peer_session.mojom.h" |
| #include "remoting/host/peer_session.h" |
| #include "remoting/protocol/ice_config_fetcher.h" |
| #include "remoting/protocol/transport.h" |
| #include "remoting/signaling/jingle_data_structures.h" |
| |
| namespace remoting { |
| |
| // Proxy implementation of `PeerSession` that communicates with the remote |
| // `PeerSessionImpl` in the dedicated Peer Connection process over Mojo IPC. |
| class IpcPeerSession : public PeerSession, |
| public protocol::Transport, |
| public mojom::TransportEventHandler, |
| public mojom::IceConfigFetcher, |
| public mojom::PairingRequester, |
| public mojom::DesktopSessionRequester { |
| public: |
| using GetDesktopSessionCallback = base::RepeatingCallback<void( |
| mojo::PendingReceiver<mojom::DesktopSession>, |
| mojo::PendingRemote<mojom::DesktopSessionEvents>, |
| mojom::DesktopSessionOptionsPtr)>; |
| |
| IpcPeerSession( |
| mojo::PendingRemote<mojom::PeerSession> peer_session_remote, |
| GetDesktopSessionCallback get_desktop_session_callback, |
| std::unique_ptr<protocol::IceConfigFetcher> ice_config_fetcher, |
| PeerSessionFactory::RequestPairingOnceCallback request_pairing_cb); |
| IpcPeerSession(const IpcPeerSession&) = delete; |
| IpcPeerSession& operator=(const IpcPeerSession&) = delete; |
| ~IpcPeerSession() override; |
| |
| // PeerSession interface: |
| void Start(EventHandler* event_handler, |
| std::string_view client_jid, |
| const DesktopEnvironmentOptions& desktop_environment_options, |
| const SessionPolicies& session_policies, |
| const SessionOptions& session_options) override; |
| void DisconnectSession(protocol::ErrorCode error, |
| std::string_view error_details, |
| const SourceLocation& error_location) override; |
| void OnSessionServicesClientConnected( |
| mojo::PendingReceiver<mojom::ChromotingSessionServices> receiver) |
| override; |
| protocol::Transport* transport() override; |
| |
| // protocol::Transport interface: |
| void Start(const std::string& auth_key, |
| SendTransportInfoCallback send_transport_info_callback) override; |
| bool ProcessTransportInfo(const JingleTransportInfo& transport_info) override; |
| |
| // mojom::TransportEventHandler interface: |
| void SendTransportInfo(const JingleTransportInfo& transport_info) override; |
| |
| // mojom::IceConfigFetcher interface: |
| void GetIceConfig(GetIceConfigCallback callback) override; |
| |
| // mojom::PairingRequester interface: |
| void RequestPairing(const std::string& client_name, |
| RequestPairingCallback callback) override; |
| |
| // mojom::DesktopSessionRequester interface: |
| void RequestDesktopSession( |
| mojo::PendingReceiver<mojom::DesktopSession> control_receiver, |
| mojo::PendingRemote<mojom::DesktopSessionEvents> events_remote, |
| const ScreenResolution& screen_resolution) override; |
| |
| private: |
| void OnPeerSessionDisconnected(); |
| void OnEventHandlerDisconnected(); |
| void NotifySessionClosed(protocol::ErrorCode error, |
| const std::string& error_details, |
| const SourceLocation& error_location); |
| void DoNotifySessionClosed(protocol::ErrorCode error, |
| const std::string& error_details, |
| const SourceLocation& error_location); |
| |
| SEQUENCE_CHECKER(sequence_checker_); |
| |
| mojo::Remote<mojom::PeerSession> remote_; |
| std::unique_ptr<mojo::Receiver<mojom::PeerSessionEventHandler>> |
| event_handler_receiver_; |
| mojo::Receiver<mojom::TransportEventHandler> |
| transport_event_handler_receiver_{this}; |
| mojo::Receiver<mojom::IceConfigFetcher> ice_config_fetcher_receiver_{this}; |
| mojo::Receiver<mojom::PairingRequester> pairing_requester_receiver_{this}; |
| mojo::Receiver<mojom::DesktopSessionRequester> |
| desktop_session_requester_receiver_{this}; |
| raw_ptr<EventHandler> event_handler_ = nullptr; |
| GetDesktopSessionCallback get_desktop_session_callback_; |
| std::unique_ptr<protocol::IceConfigFetcher> ice_config_fetcher_; |
| PeerSessionFactory::RequestPairingOnceCallback request_pairing_cb_; |
| SendTransportInfoCallback send_transport_info_callback_; |
| |
| // Options for creating the desktop session. `screen_resolution` remains |
| // unpopulated until `RequestDesktopSession()` is called. Reset to null once |
| // the desktop session is requested. |
| mojom::DesktopSessionOptionsPtr desktop_session_options_; |
| |
| base::WeakPtrFactory<IpcPeerSession> weak_factory_{this}; |
| }; |
| |
| // Factory implementation for creating `IpcPeerSession` instances over an |
| // associated Mojo interface to `PeerSessionManager` in `DaemonProcess`. |
| class IpcPeerSessionFactory : public PeerSessionFactory { |
| public: |
| using GetIceConfigFetcherCallback = |
| base::RepeatingCallback<std::unique_ptr<protocol::IceConfigFetcher>()>; |
| |
| IpcPeerSessionFactory( |
| mojo::PendingAssociatedRemote<mojom::PeerSessionManager> |
| peer_session_manager, |
| mojo::PendingAssociatedRemote<mojom::DesktopSessionManager> |
| desktop_session_manager, |
| GetIceConfigFetcherCallback get_ice_config_fetcher_cb); |
| IpcPeerSessionFactory(const IpcPeerSessionFactory&) = delete; |
| IpcPeerSessionFactory& operator=(const IpcPeerSessionFactory&) = delete; |
| ~IpcPeerSessionFactory() override; |
| |
| // PeerSessionFactory interface: |
| std::unique_ptr<PeerSession> Create() override; |
| void set_request_pairing_callback( |
| const RequestPairingCallback& request_pairing_cb) override; |
| |
| // If set to a non-empty value, the login user of the desktop session must |
| // match `username`. |
| void SetRequiredUsername(std::string_view username); |
| |
| private: |
| void EnsureBound(); |
| void OnPeerSessionManagerDisconnected(); |
| void OnDesktopSessionManagerDisconnected(); |
| |
| void GetDesktopSession( |
| mojo::PendingReceiver<mojom::DesktopSession> control_receiver, |
| mojo::PendingRemote<mojom::DesktopSessionEvents> events_remote, |
| mojom::DesktopSessionOptionsPtr options); |
| |
| SEQUENCE_CHECKER(sequence_checker_); |
| |
| std::string required_username_; |
| |
| mojo::PendingAssociatedRemote<mojom::PeerSessionManager> |
| pending_peer_session_manager_; |
| mojo::PendingAssociatedRemote<mojom::DesktopSessionManager> |
| pending_desktop_session_manager_; |
| mojo::AssociatedRemote<mojom::PeerSessionManager> peer_session_manager_; |
| mojo::AssociatedRemote<mojom::DesktopSessionManager> desktop_session_manager_; |
| GetIceConfigFetcherCallback get_ice_config_fetcher_cb_; |
| RequestPairingCallback request_pairing_cb_; |
| |
| base::WeakPtrFactory<IpcPeerSessionFactory> weak_factory_{this}; |
| }; |
| |
| } // namespace remoting |
| |
| #endif // REMOTING_HOST_IPC_PEER_SESSION_H_ |