| // Copyright 2012 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_CLIENT_SESSION_H_ |
| #define REMOTING_HOST_CLIENT_SESSION_H_ |
| |
| #include <cstdint> |
| #include <memory> |
| #include <optional> |
| #include <string> |
| #include <string_view> |
| #include <vector> |
| |
| #include "base/callback_list.h" |
| #include "base/functional/callback_forward.h" |
| #include "base/location.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/task/single_thread_task_runner.h" |
| #include "base/timer/timer.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/host_experiment_session_plugin.h" |
| #include "remoting/host/peer_session.h" |
| #include "remoting/protocol/connection_to_client.h" |
| #include "remoting/protocol/errors.h" |
| #include "remoting/protocol/pairing_registry.h" |
| #include "remoting/protocol/session.h" |
| |
| namespace remoting { |
| |
| // A ClientSession keeps a reference to a connection to a client, and maintains |
| // per-client state. |
| class ClientSession : public protocol::Session::EventHandler, |
| public PeerSession::EventHandler { |
| public: |
| // Callback interface for passing events to the ChromotingHost. |
| class EventHandler { |
| public: |
| // Called after authentication has started. |
| virtual void OnSessionAuthenticating(ClientSession* client) = 0; |
| |
| // Called after authentication has finished successfully. |
| virtual void OnSessionAuthenticated(ClientSession* client) = 0; |
| |
| // Called after we've finished connecting all channels. |
| virtual void OnSessionChannelsConnected(ClientSession* client) = 0; |
| |
| // Called after authentication has failed. Must not tear down this |
| // object. OnSessionClosed() is notified after this handler |
| // returns. |
| virtual void OnSessionAuthenticationFailed(ClientSession* client) = 0; |
| |
| // Called after connection has failed or after the client closed it. |
| virtual void OnSessionClosed(ClientSession* client) = 0; |
| |
| // Called on notification of a route change event, when a channel is |
| // connected. |
| virtual void OnSessionRouteChange( |
| ClientSession* client, |
| const std::string& channel_name, |
| const protocol::TransportRoute& route) = 0; |
| |
| // Called when session policies are received. Returns nullopt if the session |
| // policies are valid; otherwise returns an error code, which will be used |
| // to close the session with. |
| virtual std::optional<ErrorCode> OnSessionPoliciesReceived( |
| const SessionPolicies& policies) = 0; |
| |
| protected: |
| virtual ~EventHandler() {} |
| }; |
| |
| // `event_handler` and `peer_session_factory` must outlive `this`. |
| ClientSession( |
| EventHandler* event_handler, |
| std::unique_ptr<protocol::Session> session, |
| PeerSessionFactory* peer_session_factory, |
| const DesktopEnvironmentOptions& desktop_environment_options, |
| const LocalSessionPoliciesProvider* local_session_policies_provider); |
| |
| ClientSession(const ClientSession&) = delete; |
| ClientSession& operator=(const ClientSession&) = delete; |
| |
| ~ClientSession() override; |
| |
| PeerSession* peer_session() const { return peer_session_.get(); } |
| |
| // PeerSession::EventHandler interface. |
| void OnSessionChannelsConnected() override; |
| void OnSessionClosed(protocol::ErrorCode error, |
| const std::string& error_details, |
| const SourceLocation& error_location) override; |
| void OnSessionRouteChange(const std::string& channel_name, |
| const protocol::TransportRoute& route) override; |
| |
| const std::string& client_jid() const; |
| void DisconnectSession(ErrorCode error, |
| std::string_view error_details, |
| const SourceLocation& error_location); |
| |
| void OnSessionServicesClientConnected( |
| mojo::PendingReceiver<mojom::ChromotingSessionServices> receiver); |
| |
| // protocol::Session::EventHandler interface. |
| void OnSessionStateChange(protocol::Session::State state) override; |
| |
| bool is_authenticated() const { return is_authenticated_; } |
| |
| bool channels_connected() const { return channels_connected_; } |
| |
| const SessionPolicies& effective_policies_for_tests() const { |
| return effective_policies_; |
| } |
| |
| private: |
| friend class ClientSessionTest; |
| friend class ChromotingHostTest; |
| |
| void OnConnectionAuthenticating(); |
| void OnConnectionAuthenticated(const SessionPolicies* session_policies); |
| |
| void OnLocalSessionPoliciesChanged(const SessionPolicies& new_policies); |
| |
| raw_ptr<EventHandler> event_handler_; |
| |
| // The DesktopEnvironmentOptions used to initialize DesktopEnvironment. |
| DesktopEnvironmentOptions desktop_environment_options_; |
| |
| // Set to true if the client was authenticated successfully. |
| bool is_authenticated_ = false; |
| |
| // Set to true after all data channels have been connected. |
| bool channels_connected_ = false; |
| |
| // Factory to create `PeerSession` objects. |
| raw_ptr<PeerSessionFactory> peer_session_factory_; |
| |
| // The signaling session. |
| std::unique_ptr<protocol::Session> session_; |
| |
| // Object to control the peer session. It is created after AUTHENTICATED. |
| std::unique_ptr<PeerSession> peer_session_; |
| |
| // True if ClientSession teardown has already begun. Prevents re-entrant |
| // execution of OnConnectionClosed() when callbacks fire during teardown. |
| bool is_closing_ = false; |
| |
| std::string client_jid_; |
| |
| HostExperimentSessionPlugin host_experiment_session_plugin_; |
| |
| SessionPolicies effective_policies_; |
| |
| raw_ptr<const LocalSessionPoliciesProvider> local_session_policies_provider_; |
| |
| // If `effective_policies` does not come from local session policies, the |
| // subscription will be null and OnLocalSessionPoliciesChanged() will never |
| // be called. |
| base::CallbackListSubscription local_session_policy_update_subscription_; |
| |
| std::vector<mojo::PendingReceiver<mojom::ChromotingSessionServices>> |
| pending_session_services_receivers_; |
| |
| base::OneShotTimer max_duration_timer_; |
| |
| SEQUENCE_CHECKER(sequence_checker_); |
| |
| // Used to disable callbacks to `this` once DisconnectSession() has been |
| // called. |
| base::WeakPtrFactory<ClientSession> weak_factory_{this}; |
| }; |
| |
| } // namespace remoting |
| |
| #endif // REMOTING_HOST_CLIENT_SESSION_H_ |