blob: c7837eccddaeb9a02e9d90e0776d922a032d389c [file] [log] [blame]
[email protected]e265ad72012-03-16 17:28:031// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]409ac612011-11-18 04:05:572// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "remoting/protocol/client_control_dispatcher.h"
6
avi5a080f012015-12-22 23:15:437#include <stdint.h>
8
[email protected]c6944272012-01-06 22:12:289#include "base/bind_helpers.h"
10#include "base/callback.h"
[email protected]2e8b52c2011-11-22 00:07:1311#include "net/socket/stream_socket.h"
sergeyuf1005f62016-02-03 21:11:3012#include "remoting/base/compound_buffer.h"
[email protected]2e8b52c2011-11-22 00:07:1313#include "remoting/base/constants.h"
[email protected]409ac612011-11-18 04:05:5714#include "remoting/proto/control.pb.h"
[email protected]409ac612011-11-18 04:05:5715#include "remoting/proto/internal.pb.h"
16#include "remoting/protocol/client_stub.h"
sergeyuf1005f62016-02-03 21:11:3017#include "remoting/protocol/message_pipe.h"
[email protected]b76a2742014-04-10 05:38:2618#include "remoting/protocol/message_serialization.h"
[email protected]409ac612011-11-18 04:05:5719
20namespace remoting {
21namespace protocol {
22
[email protected]cb959342013-09-12 05:39:0223namespace {
24
25// 32-bit BGRA is 4 bytes per pixel.
26const int kBytesPerPixel = 4;
27
28bool CursorShapeIsValid(const CursorShapeInfo& cursor_shape) {
29 if (!cursor_shape.has_data() ||
30 !cursor_shape.has_width() ||
31 !cursor_shape.has_height() ||
32 !cursor_shape.has_hotspot_x() ||
33 !cursor_shape.has_hotspot_y()) {
34 LOG(ERROR) << "Cursor shape is missing required fields.";
35 return false;
36 }
37
38 int width = cursor_shape.width();
39 int height = cursor_shape.height();
40
41 // Verify that |width| and |height| are within sane limits. Otherwise integer
42 // overflow can occur while calculating |cursor_total_bytes| below.
kelvinpefa63e02015-01-06 23:50:0743 if (width < 0 || width > (SHRT_MAX / 2) ||
44 height < 0 || height > (SHRT_MAX / 2)) {
[email protected]cb959342013-09-12 05:39:0245 LOG(ERROR) << "Cursor dimensions are out of bounds for SetCursor: "
46 << width << "x" << height;
47 return false;
48 }
49
avi5a080f012015-12-22 23:15:4350 uint32_t cursor_total_bytes = width * height * kBytesPerPixel;
[email protected]cb959342013-09-12 05:39:0251 if (cursor_shape.data().size() < cursor_total_bytes) {
52 LOG(ERROR) << "Expected " << cursor_total_bytes << " bytes for a "
53 << width << "x" << height << " cursor. Only received "
54 << cursor_shape.data().size() << " bytes";
55 return false;
56 }
57
58 return true;
59}
60
61} // namespace
62
[email protected]409ac612011-11-18 04:05:5763ClientControlDispatcher::ClientControlDispatcher()
sergeyud8af2ca2016-01-30 03:04:3664 : ChannelDispatcherBase(kControlChannelName) {}
Chris Watkins6fe52aa2017-11-28 03:24:0565ClientControlDispatcher::~ClientControlDispatcher() = default;
[email protected]409ac612011-11-18 04:05:5766
[email protected]e265ad72012-03-16 17:28:0367void ClientControlDispatcher::InjectClipboardEvent(
68 const ClipboardEvent& event) {
69 ControlMessage message;
70 message.mutable_clipboard_event()->CopyFrom(event);
sergeyuf1005f62016-02-03 21:11:3071 message_pipe()->Send(&message, base::Closure());
[email protected]e265ad72012-03-16 17:28:0372}
73
[email protected]48a8ca32013-02-13 04:31:0174void ClientControlDispatcher::NotifyClientResolution(
75 const ClientResolution& resolution) {
[email protected]f2b9cf32012-04-27 00:13:4376 ControlMessage message;
[email protected]48a8ca32013-02-13 04:31:0177 message.mutable_client_resolution()->CopyFrom(resolution);
sergeyuf1005f62016-02-03 21:11:3078 message_pipe()->Send(&message, base::Closure());
[email protected]f2b9cf32012-04-27 00:13:4379}
80
[email protected]50d71c72012-05-03 01:28:5581void ClientControlDispatcher::ControlVideo(const VideoControl& video_control) {
82 ControlMessage message;
83 message.mutable_video_control()->CopyFrom(video_control);
sergeyuf1005f62016-02-03 21:11:3084 message_pipe()->Send(&message, base::Closure());
[email protected]50d71c72012-05-03 01:28:5585}
86
[email protected]f458bed2012-10-18 03:27:5987void ClientControlDispatcher::ControlAudio(const AudioControl& audio_control) {
88 ControlMessage message;
89 message.mutable_audio_control()->CopyFrom(audio_control);
sergeyuf1005f62016-02-03 21:11:3090 message_pipe()->Send(&message, base::Closure());
[email protected]f458bed2012-10-18 03:27:5991}
92
[email protected]a5d181f2013-04-19 14:55:3793void ClientControlDispatcher::SetCapabilities(
94 const Capabilities& capabilities) {
95 ControlMessage message;
96 message.mutable_capabilities()->CopyFrom(capabilities);
sergeyuf1005f62016-02-03 21:11:3097 message_pipe()->Send(&message, base::Closure());
[email protected]a5d181f2013-04-19 14:55:3798}
99
[email protected]9ffa78a22013-05-10 04:35:10100void ClientControlDispatcher::RequestPairing(
101 const PairingRequest& pairing_request) {
102 ControlMessage message;
103 message.mutable_pairing_request()->CopyFrom(pairing_request);
sergeyuf1005f62016-02-03 21:11:30104 message_pipe()->Send(&message, base::Closure());
[email protected]9ffa78a22013-05-10 04:35:10105}
106
[email protected]09eabd65c2013-08-13 00:13:48107void ClientControlDispatcher::DeliverClientMessage(
108 const ExtensionMessage& message) {
109 ControlMessage control_message;
110 control_message.mutable_extension_message()->CopyFrom(message);
sergeyuf1005f62016-02-03 21:11:30111 message_pipe()->Send(&control_message, base::Closure());
[email protected]09eabd65c2013-08-13 00:13:48112}
113
sergeyud8af2ca2016-01-30 03:04:36114void ClientControlDispatcher::OnIncomingMessage(
dcheng0765c492016-04-06 22:41:53115 std::unique_ptr<CompoundBuffer> buffer) {
[email protected]409ac612011-11-18 04:05:57116 DCHECK(client_stub_);
[email protected]ba6d1c2d2012-03-31 01:28:38117 DCHECK(clipboard_stub_);
[email protected]ba6d1c2d2012-03-31 01:28:38118
dcheng0765c492016-04-06 22:41:53119 std::unique_ptr<ControlMessage> message =
sergeyud8af2ca2016-01-30 03:04:36120 ParseMessage<ControlMessage>(buffer.get());
121 if (!message)
122 return;
123
[email protected]ba6d1c2d2012-03-31 01:28:38124 if (message->has_clipboard_event()) {
125 clipboard_stub_->InjectClipboardEvent(message->clipboard_event());
[email protected]a5d181f2013-04-19 14:55:37126 } else if (message->has_capabilities()) {
127 client_stub_->SetCapabilities(message->capabilities());
[email protected]d65e15bd2012-06-02 22:16:41128 } else if (message->has_cursor_shape()) {
[email protected]cb959342013-09-12 05:39:02129 if (CursorShapeIsValid(message->cursor_shape()))
130 client_stub_->SetCursorShape(message->cursor_shape());
[email protected]9ffa78a22013-05-10 04:35:10131 } else if (message->has_pairing_response()) {
132 client_stub_->SetPairingResponse(message->pairing_response());
[email protected]09eabd65c2013-08-13 00:13:48133 } else if (message->has_extension_message()) {
134 client_stub_->DeliverHostMessage(message->extension_message());
sergeyu00a67b12016-04-01 00:07:00135 } else if (message->has_video_layout()) {
136 client_stub_->SetVideoLayout(message->video_layout());
[email protected]ba6d1c2d2012-03-31 01:28:38137 } else {
138 LOG(WARNING) << "Unknown control message received.";
139 }
[email protected]409ac612011-11-18 04:05:57140}
141
142} // namespace protocol
143} // namespace remoting