client_control_dispatcher.cc 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. // Copyright (c) 2012 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/protocol/client_control_dispatcher.h"
  5. #include <stdint.h>
  6. #include "base/callback.h"
  7. #include "base/callback_helpers.h"
  8. #include "net/socket/stream_socket.h"
  9. #include "remoting/base/compound_buffer.h"
  10. #include "remoting/base/constants.h"
  11. #include "remoting/proto/control.pb.h"
  12. #include "remoting/proto/internal.pb.h"
  13. #include "remoting/protocol/client_stub.h"
  14. #include "remoting/protocol/message_pipe.h"
  15. #include "remoting/protocol/message_serialization.h"
  16. namespace remoting {
  17. namespace protocol {
  18. namespace {
  19. // 32-bit BGRA is 4 bytes per pixel.
  20. const int kBytesPerPixel = 4;
  21. bool CursorShapeIsValid(const CursorShapeInfo& cursor_shape) {
  22. if (!cursor_shape.has_data() ||
  23. !cursor_shape.has_width() ||
  24. !cursor_shape.has_height() ||
  25. !cursor_shape.has_hotspot_x() ||
  26. !cursor_shape.has_hotspot_y()) {
  27. LOG(ERROR) << "Cursor shape is missing required fields.";
  28. return false;
  29. }
  30. int width = cursor_shape.width();
  31. int height = cursor_shape.height();
  32. // Verify that |width| and |height| are within sane limits. Otherwise integer
  33. // overflow can occur while calculating |cursor_total_bytes| below.
  34. if (width < 0 || width > (SHRT_MAX / 2) ||
  35. height < 0 || height > (SHRT_MAX / 2)) {
  36. LOG(ERROR) << "Cursor dimensions are out of bounds for SetCursor: "
  37. << width << "x" << height;
  38. return false;
  39. }
  40. uint32_t cursor_total_bytes = width * height * kBytesPerPixel;
  41. if (cursor_shape.data().size() < cursor_total_bytes) {
  42. LOG(ERROR) << "Expected " << cursor_total_bytes << " bytes for a "
  43. << width << "x" << height << " cursor. Only received "
  44. << cursor_shape.data().size() << " bytes";
  45. return false;
  46. }
  47. return true;
  48. }
  49. } // namespace
  50. ClientControlDispatcher::ClientControlDispatcher()
  51. : ChannelDispatcherBase(kControlChannelName) {}
  52. ClientControlDispatcher::~ClientControlDispatcher() = default;
  53. void ClientControlDispatcher::InjectClipboardEvent(
  54. const ClipboardEvent& event) {
  55. ControlMessage message;
  56. message.mutable_clipboard_event()->CopyFrom(event);
  57. message_pipe()->Send(&message, {});
  58. }
  59. void ClientControlDispatcher::NotifyClientResolution(
  60. const ClientResolution& resolution) {
  61. ControlMessage message;
  62. message.mutable_client_resolution()->CopyFrom(resolution);
  63. message_pipe()->Send(&message, {});
  64. }
  65. void ClientControlDispatcher::ControlVideo(const VideoControl& video_control) {
  66. ControlMessage message;
  67. message.mutable_video_control()->CopyFrom(video_control);
  68. message_pipe()->Send(&message, {});
  69. }
  70. void ClientControlDispatcher::ControlAudio(const AudioControl& audio_control) {
  71. ControlMessage message;
  72. message.mutable_audio_control()->CopyFrom(audio_control);
  73. message_pipe()->Send(&message, {});
  74. }
  75. void ClientControlDispatcher::SetCapabilities(
  76. const Capabilities& capabilities) {
  77. ControlMessage message;
  78. message.mutable_capabilities()->CopyFrom(capabilities);
  79. message_pipe()->Send(&message, {});
  80. }
  81. void ClientControlDispatcher::RequestPairing(
  82. const PairingRequest& pairing_request) {
  83. ControlMessage message;
  84. message.mutable_pairing_request()->CopyFrom(pairing_request);
  85. message_pipe()->Send(&message, {});
  86. }
  87. void ClientControlDispatcher::DeliverClientMessage(
  88. const ExtensionMessage& message) {
  89. ControlMessage control_message;
  90. control_message.mutable_extension_message()->CopyFrom(message);
  91. message_pipe()->Send(&control_message, {});
  92. }
  93. void ClientControlDispatcher::SelectDesktopDisplay(
  94. const SelectDesktopDisplayRequest& select_display) {
  95. ControlMessage message;
  96. message.mutable_select_display()->CopyFrom(select_display);
  97. message_pipe()->Send(&message, {});
  98. }
  99. void ClientControlDispatcher::ControlPeerConnection(
  100. const protocol::PeerConnectionParameters& parameters) {
  101. ControlMessage message;
  102. message.mutable_peer_connection_parameters()->CopyFrom(parameters);
  103. message_pipe()->Send(&message, {});
  104. }
  105. void ClientControlDispatcher::OnIncomingMessage(
  106. std::unique_ptr<CompoundBuffer> buffer) {
  107. DCHECK(client_stub_);
  108. DCHECK(clipboard_stub_);
  109. std::unique_ptr<ControlMessage> message =
  110. ParseMessage<ControlMessage>(buffer.get());
  111. if (!message)
  112. return;
  113. if (message->has_clipboard_event()) {
  114. clipboard_stub_->InjectClipboardEvent(message->clipboard_event());
  115. } else if (message->has_capabilities()) {
  116. client_stub_->SetCapabilities(message->capabilities());
  117. } else if (message->has_cursor_shape()) {
  118. if (CursorShapeIsValid(message->cursor_shape()))
  119. client_stub_->SetCursorShape(message->cursor_shape());
  120. } else if (message->has_pairing_response()) {
  121. client_stub_->SetPairingResponse(message->pairing_response());
  122. } else if (message->has_extension_message()) {
  123. client_stub_->DeliverHostMessage(message->extension_message());
  124. } else if (message->has_video_layout()) {
  125. client_stub_->SetVideoLayout(message->video_layout());
  126. } else {
  127. LOG(WARNING) << "Unknown control message received.";
  128. }
  129. }
  130. } // namespace protocol
  131. } // namespace remoting