| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #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/callback.h" |
| #include "base/compiler_specific.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_and_cursor_conditional_composer.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/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 IPC |
| |
| namespace remoting { |
| |
| class ActionExecutor; |
| class AudioCapturer; |
| class AudioPacket; |
| class AutoThreadTaskRunner; |
| class DesktopEnvironment; |
| class DesktopEnvironmentFactory; |
| class InputInjector; |
| class KeyboardLayoutMonitor; |
| class RemoteInputFilter; |
| class RemoteWebAuthnStateChangeNotifier; |
| class ScreenControls; |
| class ScreenResolution; |
| class UrlForwarderConfigurator; |
| |
| namespace protocol { |
| class InputEventTracker; |
| } // namespace protocol |
| |
| // Provides screen/audio capturing and input injection services for |
| // the network process. |
| class DesktopSessionAgent |
| : public base::RefCountedThreadSafe<DesktopSessionAgent>, |
| public IPC::Listener, |
| public webrtc::DesktopCapturer::Callback, |
| public webrtc::MouseCursorMonitor::Callback, |
| public ClientSessionControl, |
| public IpcFileOperations::ResultHandler, |
| public mojom::DesktopSessionAgent, |
| public mojom::DesktopSessionControl { |
| public: |
| class Delegate { |
| public: |
| virtual ~Delegate(); |
| |
| // Returns an instance of desktop environment factory used. |
| virtual DesktopEnvironmentFactory& desktop_environment_factory() = 0; |
| |
| // Notifies the delegate that the network-to-desktop channel has been |
| // disconnected. |
| virtual void OnNetworkProcessDisconnected() = 0; |
| |
| // Allows the desktop process to ask the daemon process to crash the network |
| // process. This should be called any time the network process sends an |
| // invalid IPC message to the desktop process (indicating that the network |
| // process might have been compromised). |
| 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; |
| |
| // IPC::Listener implementation. |
| 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; |
| |
| // webrtc::DesktopCapturer::Callback implementation. |
| void OnCaptureResult(webrtc::DesktopCapturer::Result result, |
| std::unique_ptr<webrtc::DesktopFrame> frame) override; |
| |
| // webrtc::MouseCursorMonitor::Callback implementation. |
| void OnMouseCursor(webrtc::MouseCursor* cursor) override; |
| void OnMouseCursorPosition(const webrtc::DesktopVector& position) override; |
| |
| // Forwards a local clipboard event to the network process over IPC. |
| void OnClipboardEvent(const protocol::ClipboardEvent& event); |
| |
| // Forwards an audio packet though the IPC channel to the network process. |
| void ProcessAudioPacket(std::unique_ptr<AudioPacket> packet); |
| |
| // IpcFileOperations::ResultHandler implementation. |
| void OnResult(std::uint64_t file_id, ResultHandler::Result result) override; |
| void OnInfoResult(std::uint64_t file_id, |
| ResultHandler::InfoResult result) override; |
| void OnDataResult(std::uint64_t file_id, |
| ResultHandler::DataResult result) override; |
| |
| // mojom::DesktopSessionAgent implementation. |
| void Start(const std::string& authenticated_jid, |
| const ScreenResolution& resolution, |
| const DesktopEnvironmentOptions& options, |
| StartCallback callback) override; |
| |
| // mojom::DesktopSessionControl implementation. |
| 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; |
| |
| // Creates desktop integration components and a connected IPC channel to be |
| // used to access them. The client end of the channel is returned. |
| mojo::ScopedMessagePipeHandle Initialize( |
| const base::WeakPtr<Delegate>& delegate); |
| |
| // Stops the agent asynchronously. |
| void Stop(); |
| |
| protected: |
| friend class base::RefCountedThreadSafe<DesktopSessionAgent>; |
| |
| ~DesktopSessionAgent() override; |
| |
| // ClientSessionControl interface. |
| 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; |
| |
| // Handles keyboard layout changes. |
| void OnKeyboardLayoutChange(const protocol::KeyboardLayout& layout); |
| |
| // Notifies the network process when a new shared memory region is created. |
| void OnSharedMemoryRegionCreated(int id, |
| base::ReadOnlySharedMemoryRegion region, |
| uint32_t size); |
| |
| // Notifies the network process when a shared memory region is released. |
| void OnSharedMemoryRegionReleased(int id); |
| |
| // Sends a message to the network process. |
| void SendToNetwork(std::unique_ptr<IPC::Message> message); |
| |
| // Posted to |audio_capture_task_runner_| to start the audio capturer. |
| void StartAudioCapturer(); |
| |
| // Posted to |audio_capture_task_runner_| to stop the audio capturer. |
| void StopAudioCapturer(); |
| |
| private: |
| void OnCheckUrlForwarderSetUpResult(bool is_set_up); |
| void OnUrlForwarderSetUpStateChanged( |
| protocol::UrlForwarderControl::SetUpUrlForwarderResponse::State state); |
| |
| // Task runner dedicated to running methods of |audio_capturer_|. |
| scoped_refptr<AutoThreadTaskRunner> audio_capture_task_runner_; |
| |
| // Task runner on which public methods of this class should be called. |
| scoped_refptr<AutoThreadTaskRunner> caller_task_runner_; |
| |
| // Task runner on which keyboard/mouse input is injected. |
| scoped_refptr<AutoThreadTaskRunner> input_task_runner_; |
| |
| // Task runner used by the IPC channel. |
| scoped_refptr<AutoThreadTaskRunner> io_task_runner_; |
| |
| // Captures audio output. |
| std::unique_ptr<AudioCapturer> audio_capturer_; |
| |
| std::string client_jid_; |
| |
| base::WeakPtr<Delegate> delegate_; |
| |
| // The DesktopEnvironment instance used by this agent. |
| std::unique_ptr<DesktopEnvironment> desktop_environment_; |
| |
| // Executes action request events. |
| std::unique_ptr<ActionExecutor> action_executor_; |
| |
| // Executes keyboard, mouse and clipboard events. |
| std::unique_ptr<InputInjector> input_injector_; |
| |
| // Tracker used to release pressed keys and buttons when disconnecting. |
| std::unique_ptr<protocol::InputEventTracker> input_tracker_; |
| |
| // Filter used to disable remote inputs during local input activity. |
| std::unique_ptr<RemoteInputFilter> remote_input_filter_; |
| |
| // Used to apply client-requested changes in screen resolution. |
| std::unique_ptr<ScreenControls> screen_controls_; |
| |
| // IPC channel connecting the desktop process with the network process. |
| std::unique_ptr<IPC::ChannelProxy> network_channel_; |
| |
| // True if the desktop session agent has been started. |
| bool started_ = false; |
| |
| // Captures the screen and composites with the mouse cursor if necessary. |
| std::unique_ptr<DesktopAndCursorConditionalComposer> video_capturer_; |
| |
| // Captures mouse shapes. |
| std::unique_ptr<webrtc::MouseCursorMonitor> mouse_cursor_monitor_; |
| |
| // Watches for keyboard layout changes. |
| std::unique_ptr<KeyboardLayoutMonitor> keyboard_layout_monitor_; |
| |
| // Keep reference to the last frame sent to make sure shared buffer is alive |
| // before it's received. |
| std::unique_ptr<webrtc::DesktopFrame> last_frame_; |
| |
| // Routes file-transfer messages to the corresponding reader/writer to be |
| // executed. |
| 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}; |
| |
| // Checks and configures the URL forwarder. |
| std::unique_ptr<::remoting::UrlForwarderConfigurator> |
| url_forwarder_configurator_; |
| |
| std::unique_ptr<RemoteWebAuthnStateChangeNotifier> |
| webauthn_state_change_notifier_; |
| |
| // Used to disable callbacks to |this|. |
| base::WeakPtrFactory<DesktopSessionAgent> weak_factory_{this}; |
| }; |
| |
| } // namespace remoting |
| |
| #endif // REMOTING_HOST_DESKTOP_SESSION_AGENT_H_ |