[go: nahoru, domu]

blob: 7fbfe24527f13c759538e5c9fba842cfb06dd691 [file] [log] [blame]
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "remoting/host/mojom/remoting_mojom_traits.h"
namespace mojo {
// static
bool mojo::StructTraits<remoting::mojom::AudioPacketDataView,
::std::unique_ptr<::remoting::AudioPacket>>::
Read(remoting::mojom::AudioPacketDataView data_view,
::std::unique_ptr<::remoting::AudioPacket>* out_packet) {
auto packet = std::make_unique<::remoting::AudioPacket>();
packet->set_timestamp(data_view.timestamp());
if (!data_view.ReadData(packet->mutable_data())) {
return false;
}
::remoting::AudioPacket::Encoding encoding;
if (!data_view.ReadEncoding(&encoding)) {
return false;
}
packet->set_encoding(encoding);
::remoting::AudioPacket::SamplingRate sampling_rate;
if (!data_view.ReadSamplingRate(&sampling_rate)) {
return false;
}
packet->set_sampling_rate(sampling_rate);
::remoting::AudioPacket::BytesPerSample bytes_per_sample;
if (!data_view.ReadBytesPerSample(&bytes_per_sample)) {
return false;
}
packet->set_bytes_per_sample(bytes_per_sample);
::remoting::AudioPacket::Channels channels;
if (!data_view.ReadChannels(&channels)) {
return false;
}
packet->set_channels(channels);
*out_packet = std::move(packet);
return true;
}
// static
bool mojo::StructTraits<remoting::mojom::ClipboardEventDataView,
::remoting::protocol::ClipboardEvent>::
Read(remoting::mojom::ClipboardEventDataView data_view,
::remoting::protocol::ClipboardEvent* out_event) {
std::string mime_type;
if (!data_view.ReadMimeType(&mime_type)) {
return false;
}
out_event->set_mime_type(std::move(mime_type));
std::string data;
if (!data_view.ReadData(&data)) {
return false;
}
out_event->set_data(std::move(data));
return true;
}
// static
bool mojo::StructTraits<remoting::mojom::DesktopCaptureOptionsDataView,
::webrtc::DesktopCaptureOptions>::
Read(remoting::mojom::DesktopCaptureOptionsDataView data_view,
::webrtc::DesktopCaptureOptions* out_options) {
out_options->set_use_update_notifications(
data_view.use_update_notifications());
out_options->set_detect_updated_region(data_view.detect_updated_region());
#if BUILDFLAG(IS_WIN)
out_options->set_allow_directx_capturer(data_view.allow_directx_capturer());
#endif // BUILDFLAG(IS_WIN)
return true;
}
// static
bool mojo::StructTraits<remoting::mojom::DesktopEnvironmentOptionsDataView,
::remoting::DesktopEnvironmentOptions>::
Read(remoting::mojom::DesktopEnvironmentOptionsDataView data_view,
::remoting::DesktopEnvironmentOptions* out_options) {
out_options->set_enable_curtaining(data_view.enable_curtaining());
out_options->set_enable_user_interface(data_view.enable_user_interface());
out_options->set_enable_notifications(data_view.enable_notifications());
out_options->set_terminate_upon_input(data_view.terminate_upon_input());
out_options->set_enable_file_transfer(data_view.enable_file_transfer());
out_options->set_enable_remote_open_url(data_view.enable_remote_open_url());
out_options->set_enable_remote_webauthn(data_view.enable_remote_webauthn());
absl::optional<uint32_t> clipboard_size;
if (!data_view.ReadClipboardSize(&clipboard_size)) {
return false;
}
if (clipboard_size.has_value()) {
out_options->set_clipboard_size(std::move(clipboard_size));
}
if (!data_view.ReadDesktopCaptureOptions(
out_options->desktop_capture_options())) {
return false;
}
return true;
}
// static
bool mojo::StructTraits<
remoting::mojom::DesktopRectDataView,
::webrtc::DesktopRect>::Read(remoting::mojom::DesktopRectDataView data_view,
::webrtc::DesktopRect* out_rect) {
*out_rect = webrtc::DesktopRect::MakeLTRB(
data_view.left(), data_view.top(), data_view.right(), data_view.bottom());
return true;
}
// static
bool mojo::StructTraits<
remoting::mojom::DesktopSizeDataView,
::webrtc::DesktopSize>::Read(remoting::mojom::DesktopSizeDataView data_view,
::webrtc::DesktopSize* out_size) {
out_size->set(data_view.width(), data_view.height());
return true;
}
// static
bool mojo::StructTraits<remoting::mojom::DesktopVectorDataView,
::webrtc::DesktopVector>::
Read(remoting::mojom::DesktopVectorDataView data_view,
::webrtc::DesktopVector* out_vector) {
out_vector->set(data_view.x(), data_view.y());
return true;
}
#if BUILDFLAG(IS_WIN)
// static
bool mojo::UnionTraits<
remoting::mojom::FileChooserResultDataView,
::remoting::Result<base::FilePath,
::remoting::protocol::FileTransfer_Error>>::
Read(remoting::mojom::FileChooserResultDataView data_view,
::remoting::Result<base::FilePath,
::remoting::protocol::FileTransfer_Error>*
out_result) {
switch (data_view.tag()) {
case remoting::mojom::FileChooserResultDataView::Tag::kFilepath: {
base::FilePath filepath;
if (!data_view.ReadFilepath(&filepath)) {
return false;
}
out_result->EmplaceSuccess(std::move(filepath));
return true;
}
case remoting::mojom::FileChooserResultDataView::Tag::kError: {
::remoting::protocol::FileTransfer_Error error;
if (!data_view.ReadError(&error)) {
return false;
}
out_result->EmplaceError(std::move(error));
return true;
}
}
}
#endif // BUILDFLAG(IS_WIN)
// static
bool mojo::UnionTraits<
remoting::mojom::ReadChunkResultDataView,
::remoting::Result<std::vector<uint8_t>,
::remoting::protocol::FileTransfer_Error>>::
Read(remoting::mojom::ReadChunkResultDataView data_view,
::remoting::Result<std::vector<uint8_t>,
::remoting::protocol::FileTransfer_Error>*
out_result) {
switch (data_view.tag()) {
case remoting::mojom::ReadChunkResultDataView::Tag::kData: {
std::vector<uint8_t> data;
if (!data_view.ReadData(&data)) {
return false;
}
out_result->EmplaceSuccess(std::move(data));
return true;
}
case remoting::mojom::ReadChunkResultDataView::Tag::kError: {
::remoting::protocol::FileTransfer_Error error;
if (!data_view.ReadError(&error)) {
return false;
}
out_result->EmplaceError(std::move(error));
return true;
}
}
}
// static
bool mojo::StructTraits<remoting::mojom::FileTransferErrorDataView,
::remoting::protocol::FileTransfer_Error>::
Read(remoting::mojom::FileTransferErrorDataView data_view,
::remoting::protocol::FileTransfer_Error* out_error) {
::remoting::protocol::FileTransfer_Error_Type type;
if (!data_view.ReadType(&type)) {
return false;
}
out_error->set_type(type);
absl::optional<int32_t> api_error_code;
if (!data_view.ReadApiErrorCode(&api_error_code)) {
return false;
}
if (api_error_code) {
out_error->set_api_error_code(*api_error_code);
}
std::string function;
if (!data_view.ReadFunction(&function)) {
return false;
}
out_error->set_function(std::move(function));
std::string source_file;
if (!data_view.ReadSourceFile(&source_file)) {
return false;
}
out_error->set_source_file(std::move(source_file));
out_error->set_line_number(data_view.line_number());
return true;
}
// static
bool mojo::StructTraits<remoting::mojom::KeyboardLayoutDataView,
::remoting::protocol::KeyboardLayout>::
Read(remoting::mojom::KeyboardLayoutDataView data_view,
::remoting::protocol::KeyboardLayout* out_layout) {
return data_view.ReadKeys(out_layout->mutable_keys());
}
// static
bool mojo::UnionTraits<remoting::mojom::KeyActionDataView,
::remoting::protocol::KeyboardLayout_KeyAction>::
Read(remoting::mojom::KeyActionDataView data_view,
::remoting::protocol::KeyboardLayout_KeyAction* out_action) {
switch (data_view.tag()) {
case remoting::mojom::KeyActionDataView::Tag::kFunction:
::remoting::protocol::LayoutKeyFunction function;
if (!data_view.ReadFunction(&function)) {
return false;
}
out_action->set_function(function);
return true;
case remoting::mojom::KeyActionDataView::Tag::kCharacter:
std::string character;
if (!data_view.ReadCharacter(&character)) {
return false;
}
out_action->set_character(std::move(character));
return true;
}
}
// static
bool mojo::StructTraits<remoting::mojom::KeyBehaviorDataView,
::remoting::protocol::KeyboardLayout::KeyBehavior>::
Read(remoting::mojom::KeyBehaviorDataView data_view,
::remoting::protocol::KeyboardLayout::KeyBehavior* out_behavior) {
return data_view.ReadActions(out_behavior->mutable_actions());
}
// static
bool mojo::StructTraits<remoting::mojom::KeyEventDataView,
::remoting::protocol::KeyEvent>::
Read(remoting::mojom::KeyEventDataView data_view,
::remoting::protocol::KeyEvent* out_event) {
out_event->set_pressed(data_view.pressed());
out_event->set_usb_keycode(data_view.usb_keycode());
out_event->set_lock_states(data_view.lock_states());
absl::optional<bool> caps_lock_state;
if (!data_view.ReadCapsLockState(&caps_lock_state)) {
return false;
}
if (caps_lock_state.has_value()) {
out_event->set_caps_lock_state(*caps_lock_state);
}
absl::optional<bool> num_lock_state;
if (!data_view.ReadNumLockState(&num_lock_state)) {
return false;
}
if (num_lock_state.has_value()) {
out_event->set_num_lock_state(*num_lock_state);
}
return true;
}
// static
bool mojo::StructTraits<
remoting::mojom::MouseCursorDataView,
::webrtc::MouseCursor>::Read(remoting::mojom::MouseCursorDataView data_view,
::webrtc::MouseCursor* out_cursor) {
::webrtc::DesktopSize image_size;
if (!data_view.ReadImageSize(&image_size)) {
return false;
}
mojo::ArrayDataView<uint8_t> image_data;
data_view.GetImageDataDataView(&image_data);
base::CheckedNumeric<size_t> expected_image_data_size =
::webrtc::DesktopFrame::kBytesPerPixel * image_size.width() *
image_size.height();
if (!expected_image_data_size.IsValid()) {
return false;
}
// ValueOrDie() won't CHECK since we've already verified the value is valid.
if (image_data.size() != expected_image_data_size.ValueOrDie()) {
return false;
}
::webrtc::DesktopVector hotspot;
if (!data_view.ReadHotspot(&hotspot)) {
return false;
}
std::unique_ptr<::webrtc::DesktopFrame> new_frame(
new ::webrtc::BasicDesktopFrame(image_size));
memcpy(new_frame->data(), image_data.data(), image_data.size());
// ::webrtc::MouseCursor methods take a raw pointer *and* take ownership.
// TODO(joedow): Update webrtc::MouseCursor to use std::unique_ptr.
out_cursor->set_image(new_frame.release());
out_cursor->set_hotspot(hotspot);
return true;
}
// static
bool mojo::StructTraits<remoting::mojom::MouseEventDataView,
::remoting::protocol::MouseEvent>::
Read(remoting::mojom::MouseEventDataView data_view,
::remoting::protocol::MouseEvent* out_event) {
absl::optional<int32_t> x;
if (!data_view.ReadX(&x)) {
return false;
}
if (x.has_value()) {
out_event->set_x(*x);
}
absl::optional<int32_t> y;
if (!data_view.ReadY(&y)) {
return false;
}
if (y.has_value()) {
out_event->set_y(*y);
}
if (data_view.button() != remoting::mojom::MouseButton::kUndefined) {
::remoting::protocol::MouseEvent::MouseButton mouse_button;
if (!data_view.ReadButton(&mouse_button)) {
return false;
}
out_event->set_button(mouse_button);
}
absl::optional<bool> button_down;
if (!data_view.ReadButtonDown(&button_down)) {
return false;
}
if (button_down.has_value()) {
out_event->set_button_down(*button_down);
}
absl::optional<float> wheel_delta_x;
if (!data_view.ReadWheelDeltaX(&wheel_delta_x)) {
return false;
}
if (wheel_delta_x.has_value()) {
out_event->set_wheel_delta_x(*wheel_delta_x);
}
absl::optional<float> wheel_delta_y;
if (!data_view.ReadWheelDeltaY(&wheel_delta_y)) {
return false;
}
if (wheel_delta_y.has_value()) {
out_event->set_wheel_delta_y(*wheel_delta_y);
}
absl::optional<float> wheel_ticks_x;
if (!data_view.ReadWheelTicksX(&wheel_ticks_x)) {
return false;
}
if (wheel_ticks_x.has_value()) {
out_event->set_wheel_ticks_x(*wheel_ticks_x);
}
absl::optional<float> wheel_ticks_y;
if (!data_view.ReadWheelTicksY(&wheel_ticks_y)) {
return false;
}
if (wheel_ticks_y.has_value()) {
out_event->set_wheel_ticks_y(*wheel_ticks_y);
}
absl::optional<int32_t> delta_x;
if (!data_view.ReadDeltaX(&delta_x)) {
return false;
}
if (delta_x.has_value()) {
out_event->set_delta_x(*delta_x);
}
absl::optional<int32_t> delta_y;
if (!data_view.ReadDeltaY(&delta_y)) {
return false;
}
if (delta_y.has_value()) {
out_event->set_delta_y(*delta_y);
}
return true;
}
// static
bool mojo::StructTraits<remoting::mojom::ScreenResolutionDataView,
::remoting::ScreenResolution>::
Read(remoting::mojom::ScreenResolutionDataView data_view,
::remoting::ScreenResolution* out_resolution) {
::webrtc::DesktopSize desktop_size;
if (!data_view.ReadDimensions(&desktop_size)) {
return false;
}
::webrtc::DesktopVector dpi;
if (!data_view.ReadDpi(&dpi)) {
return false;
}
*out_resolution =
::remoting::ScreenResolution(std::move(desktop_size), std::move(dpi));
return true;
}
// static
bool mojo::StructTraits<remoting::mojom::TextEventDataView,
::remoting::protocol::TextEvent>::
Read(remoting::mojom::TextEventDataView data_view,
::remoting::protocol::TextEvent* out_event) {
std::string text;
if (!data_view.ReadText(&text)) {
return false;
}
out_event->set_text(std::move(text));
return true;
}
// static
bool mojo::StructTraits<remoting::mojom::TouchEventPointDataView,
::remoting::protocol::TouchEventPoint>::
Read(remoting::mojom::TouchEventPointDataView data_view,
::remoting::protocol::TouchEventPoint* out_event) {
out_event->set_id(data_view.id());
gfx::PointF position;
if (!data_view.ReadPosition(&position)) {
return false;
}
out_event->set_x(position.x());
out_event->set_y(position.y());
gfx::PointF radius;
if (!data_view.ReadRadius(&radius)) {
return false;
}
out_event->set_radius_x(radius.x());
out_event->set_radius_y(radius.y());
out_event->set_angle(data_view.angle());
out_event->set_pressure(data_view.pressure());
return true;
}
// static
bool mojo::StructTraits<remoting::mojom::TouchEventDataView,
::remoting::protocol::TouchEvent>::
Read(remoting::mojom::TouchEventDataView data_view,
::remoting::protocol::TouchEvent* out_event) {
::remoting::protocol::TouchEvent::TouchEventType touch_event_type;
if (!data_view.ReadEventType(&touch_event_type)) {
return false;
}
out_event->set_event_type(touch_event_type);
if (!data_view.ReadTouchPoints(out_event->mutable_touch_points())) {
return false;
}
return true;
}
// static
bool mojo::StructTraits<remoting::mojom::TransportRouteDataView,
::remoting::protocol::TransportRoute>::
Read(remoting::mojom::TransportRouteDataView data_view,
::remoting::protocol::TransportRoute* out_transport_route) {
if (!data_view.ReadType(&out_transport_route->type)) {
return false;
}
if (!data_view.ReadRemoteAddress(&out_transport_route->remote_address)) {
return false;
}
if (!data_view.ReadLocalAddress(&out_transport_route->local_address)) {
return false;
}
return true;
}
// static
bool mojo::StructTraits<remoting::mojom::VideoTrackLayoutDataView,
::remoting::protocol::VideoTrackLayout>::
Read(remoting::mojom::VideoTrackLayoutDataView data_view,
::remoting::protocol::VideoTrackLayout* out_track) {
out_track->set_screen_id(data_view.screen_id());
std::string media_stream_id;
if (!data_view.ReadMediaStreamId(&media_stream_id)) {
return false;
}
// Don't set |media_stream_id| if the value is empty as the client will
// misinterpret an empty protobuf value and multi-mon scenarios will break.
if (!media_stream_id.empty()) {
out_track->set_media_stream_id(std::move(media_stream_id));
}
gfx::Point position;
if (!data_view.ReadPosition(&position)) {
return false;
}
out_track->set_position_x(position.x());
out_track->set_position_y(position.y());
webrtc::DesktopSize size;
if (!data_view.ReadSize(&size)) {
return false;
}
out_track->set_width(size.width());
out_track->set_height(size.height());
webrtc::DesktopVector dpi;
if (!data_view.ReadDpi(&dpi)) {
return false;
}
out_track->set_x_dpi(dpi.x());
out_track->set_y_dpi(dpi.y());
return true;
}
// static
bool mojo::StructTraits<remoting::mojom::VideoLayoutDataView,
::remoting::protocol::VideoLayout>::
Read(remoting::mojom::VideoLayoutDataView data_view,
::remoting::protocol::VideoLayout* out_layout) {
if (!data_view.ReadTracks(out_layout->mutable_video_track())) {
return false;
}
out_layout->set_supports_full_desktop_capture(
data_view.supports_full_desktop_capture());
out_layout->set_primary_screen_id(data_view.primary_screen_id());
return true;
}
} // namespace mojo