host_window_proxy.cc 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. // Copyright 2013 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "remoting/host/host_window_proxy.h"
  5. #include <utility>
  6. #include "base/bind.h"
  7. #include "base/check_op.h"
  8. #include "base/location.h"
  9. #include "base/notreached.h"
  10. #include "base/task/single_thread_task_runner.h"
  11. #include "remoting/host/client_session_control.h"
  12. #include "remoting/proto/control.pb.h"
  13. #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
  14. #include "ui/events/event.h"
  15. namespace remoting {
  16. // Runs an instance of |HostWindow| on the |ui_task_runner_| thread.
  17. class HostWindowProxy::Core
  18. : public base::RefCountedThreadSafe<Core>,
  19. public ClientSessionControl {
  20. public:
  21. Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
  22. scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
  23. std::unique_ptr<HostWindow> host_window);
  24. Core(const Core&) = delete;
  25. Core& operator=(const Core&) = delete;
  26. // Starts |host_window_| on the |ui_task_runner_| thread.
  27. void Start(const base::WeakPtr<ClientSessionControl>& client_session_control);
  28. // Destroys |host_window_| on the |ui_task_runner_| thread.
  29. void Stop();
  30. private:
  31. friend class base::RefCountedThreadSafe<Core>;
  32. ~Core() override;
  33. // Start() and Stop() equivalents called on the |ui_task_runner_| thread.
  34. void StartOnUiThread(const std::string& client_jid);
  35. void StopOnUiThread();
  36. // ClientSessionControl interface.
  37. const std::string& client_jid() const override;
  38. void DisconnectSession(protocol::ErrorCode error) override;
  39. void OnLocalKeyPressed(uint32_t usb_keycode) override;
  40. void OnLocalPointerMoved(const webrtc::DesktopVector& position,
  41. ui::EventType type) override;
  42. void SetDisableInputs(bool disable_inputs) override;
  43. void OnDesktopDisplayChanged(
  44. std::unique_ptr<protocol::VideoLayout> layout) override;
  45. // Task runner on which public methods of this class must be called.
  46. scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_;
  47. // Task runner on which |host_window_| is running.
  48. scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
  49. // Stores the client's JID so it can be read on the |ui_task_runner_| thread.
  50. std::string client_jid_;
  51. // Used to notify the caller about the local user's actions on
  52. // the |caller_task_runner| thread.
  53. base::WeakPtr<ClientSessionControl> client_session_control_;
  54. // The wrapped |HostWindow| instance running on the |ui_task_runner_| thread.
  55. std::unique_ptr<HostWindow> host_window_;
  56. // Used to create the control pointer passed to |host_window_|.
  57. base::WeakPtrFactory<ClientSessionControl> weak_factory_{this};
  58. };
  59. HostWindowProxy::HostWindowProxy(
  60. scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
  61. scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
  62. std::unique_ptr<HostWindow> host_window) {
  63. DCHECK(caller_task_runner->BelongsToCurrentThread());
  64. // Detach |host_window| from the calling thread so that |Core| could run it on
  65. // the |ui_task_runner_| thread.
  66. DETACH_FROM_SEQUENCE(host_window->sequence_checker_);
  67. core_ = new Core(caller_task_runner, ui_task_runner, std::move(host_window));
  68. }
  69. HostWindowProxy::~HostWindowProxy() {
  70. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  71. core_->Stop();
  72. }
  73. void HostWindowProxy::Start(
  74. const base::WeakPtr<ClientSessionControl>& client_session_control) {
  75. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  76. core_->Start(client_session_control);
  77. }
  78. HostWindowProxy::Core::Core(
  79. scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
  80. scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
  81. std::unique_ptr<HostWindow> host_window)
  82. : caller_task_runner_(caller_task_runner),
  83. ui_task_runner_(ui_task_runner),
  84. host_window_(std::move(host_window)) {
  85. DCHECK(caller_task_runner->BelongsToCurrentThread());
  86. }
  87. void HostWindowProxy::Core::Start(
  88. const base::WeakPtr<ClientSessionControl>& client_session_control) {
  89. DCHECK(caller_task_runner_->BelongsToCurrentThread());
  90. DCHECK(!client_session_control_.get());
  91. DCHECK(client_session_control.get());
  92. client_session_control_ = client_session_control;
  93. ui_task_runner_->PostTask(
  94. FROM_HERE, base::BindOnce(&Core::StartOnUiThread, this,
  95. client_session_control->client_jid()));
  96. }
  97. void HostWindowProxy::Core::Stop() {
  98. DCHECK(caller_task_runner_->BelongsToCurrentThread());
  99. ui_task_runner_->PostTask(FROM_HERE,
  100. base::BindOnce(&Core::StopOnUiThread, this));
  101. }
  102. HostWindowProxy::Core::~Core() {
  103. DCHECK(!host_window_);
  104. }
  105. void HostWindowProxy::Core::StartOnUiThread(const std::string& client_jid) {
  106. DCHECK(ui_task_runner_->BelongsToCurrentThread());
  107. DCHECK(client_jid_.empty());
  108. client_jid_ = client_jid;
  109. host_window_->Start(weak_factory_.GetWeakPtr());
  110. }
  111. void HostWindowProxy::Core::StopOnUiThread() {
  112. DCHECK(ui_task_runner_->BelongsToCurrentThread());
  113. host_window_.reset();
  114. }
  115. const std::string& HostWindowProxy::Core::client_jid() const {
  116. DCHECK(ui_task_runner_->BelongsToCurrentThread());
  117. return client_jid_;
  118. }
  119. void HostWindowProxy::Core::DisconnectSession(protocol::ErrorCode error) {
  120. if (!caller_task_runner_->BelongsToCurrentThread()) {
  121. caller_task_runner_->PostTask(
  122. FROM_HERE, base::BindOnce(&Core::DisconnectSession, this, error));
  123. return;
  124. }
  125. if (client_session_control_.get())
  126. client_session_control_->DisconnectSession(error);
  127. }
  128. void HostWindowProxy::Core::OnLocalKeyPressed(uint32_t usb_keycode) {
  129. if (!caller_task_runner_->BelongsToCurrentThread()) {
  130. caller_task_runner_->PostTask(
  131. FROM_HERE, base::BindOnce(&Core::OnLocalKeyPressed, this, usb_keycode));
  132. return;
  133. }
  134. if (client_session_control_.get())
  135. client_session_control_->OnLocalKeyPressed(usb_keycode);
  136. }
  137. void HostWindowProxy::Core::OnLocalPointerMoved(
  138. const webrtc::DesktopVector& position,
  139. ui::EventType type) {
  140. if (!caller_task_runner_->BelongsToCurrentThread()) {
  141. caller_task_runner_->PostTask(
  142. FROM_HERE,
  143. base::BindOnce(&Core::OnLocalPointerMoved, this, position, type));
  144. return;
  145. }
  146. if (client_session_control_.get())
  147. client_session_control_->OnLocalPointerMoved(position, type);
  148. }
  149. void HostWindowProxy::Core::SetDisableInputs(bool disable_inputs) {
  150. if (!caller_task_runner_->BelongsToCurrentThread()) {
  151. caller_task_runner_->PostTask(
  152. FROM_HERE,
  153. base::BindOnce(&Core::SetDisableInputs, this, disable_inputs));
  154. return;
  155. }
  156. if (client_session_control_.get())
  157. client_session_control_->SetDisableInputs(disable_inputs);
  158. }
  159. void HostWindowProxy::Core::OnDesktopDisplayChanged(
  160. std::unique_ptr<protocol::VideoLayout> layout) {
  161. NOTREACHED();
  162. }
  163. } // namespace remoting