| // 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. | 
 |  | 
 | #include "content/common/content_param_traits.h" | 
 |  | 
 | #include <stddef.h> | 
 |  | 
 | #include "base/strings/string_number_conversions.h" | 
 | #include "base/unguessable_token.h" | 
 | #include "components/viz/common/surfaces/frame_sink_id.h" | 
 | #include "components/viz/common/surfaces/local_surface_id.h" | 
 | #include "components/viz/common/surfaces/surface_id.h" | 
 | #include "components/viz/common/surfaces/surface_info.h" | 
 | #include "content/common/frame_message_structs.h" | 
 | #include "ipc/ipc_mojo_message_helper.h" | 
 | #include "ipc/ipc_mojo_param_traits.h" | 
 | #include "net/base/ip_endpoint.h" | 
 | #include "third_party/blink/public/common/message_port/message_port_channel.h" | 
 | #include "third_party/blink/public/common/message_port/transferable_message.h" | 
 | #include "third_party/blink/public/mojom/message_port/message_port.mojom.h" | 
 | #include "ui/accessibility/ax_modes.h" | 
 | #include "ui/base/ui_base_features.h" | 
 | #include "ui/events/blink/web_input_event_traits.h" | 
 | // #include "ui/gfx/ipc/geometry/gfx_param_traits.h" | 
 |  | 
 | namespace IPC { | 
 |  | 
 | void ParamTraits<WebInputEventPointer>::Write(base::Pickle* m, | 
 |                                               const param_type& p) { | 
 |   m->WriteData(reinterpret_cast<const char*>(p), p->size()); | 
 | } | 
 |  | 
 | bool ParamTraits<WebInputEventPointer>::Read(const base::Pickle* m, | 
 |                                              base::PickleIterator* iter, | 
 |                                              param_type* r) { | 
 |   const char* data; | 
 |   int data_length; | 
 |   if (!iter->ReadData(&data, &data_length)) { | 
 |     NOTREACHED(); | 
 |     return false; | 
 |   } | 
 |   if (data_length < static_cast<int>(sizeof(blink::WebInputEvent))) { | 
 |     NOTREACHED(); | 
 |     return false; | 
 |   } | 
 |   param_type event = reinterpret_cast<param_type>(data); | 
 |   // Check that the data size matches that of the event. | 
 |   if (data_length != static_cast<int>(event->size())) { | 
 |     NOTREACHED(); | 
 |     return false; | 
 |   } | 
 |   const size_t expected_size_for_type = | 
 |       ui::WebInputEventTraits::GetSize(event->GetType()); | 
 |   if (data_length != static_cast<int>(expected_size_for_type)) { | 
 |     NOTREACHED(); | 
 |     return false; | 
 |   } | 
 |   *r = event; | 
 |   return true; | 
 | } | 
 |  | 
 | void ParamTraits<WebInputEventPointer>::Log(const param_type& p, | 
 |                                             std::string* l) { | 
 |   l->append("("); | 
 |   LogParam(p->size(), l); | 
 |   l->append(", "); | 
 |   LogParam(p->GetType(), l); | 
 |   l->append(", "); | 
 |   LogParam(p->TimeStamp(), l); | 
 |   l->append(")"); | 
 | } | 
 |  | 
 | void ParamTraits<blink::MessagePortChannel>::Write(base::Pickle* m, | 
 |                                                    const param_type& p) { | 
 |   ParamTraits<mojo::MessagePipeHandle>::Write(m, p.ReleaseHandle().release()); | 
 | } | 
 |  | 
 | bool ParamTraits<blink::MessagePortChannel>::Read(const base::Pickle* m, | 
 |                                                   base::PickleIterator* iter, | 
 |                                                   param_type* r) { | 
 |   mojo::MessagePipeHandle handle; | 
 |   if (!ParamTraits<mojo::MessagePipeHandle>::Read(m, iter, &handle)) | 
 |     return false; | 
 |   *r = blink::MessagePortChannel(mojo::ScopedMessagePipeHandle(handle)); | 
 |   return true; | 
 | } | 
 |  | 
 | void ParamTraits<blink::MessagePortChannel>::Log(const param_type& p, | 
 |                                                  std::string* l) {} | 
 |  | 
 | void ParamTraits<ui::AXMode>::Write(base::Pickle* m, const param_type& p) { | 
 |   IPC::WriteParam(m, p.mode()); | 
 | } | 
 |  | 
 | bool ParamTraits<ui::AXMode>::Read(const base::Pickle* m, | 
 |                                    base::PickleIterator* iter, | 
 |                                    param_type* r) { | 
 |   uint32_t value; | 
 |   if (!IPC::ReadParam(m, iter, &value)) | 
 |     return false; | 
 |   *r = ui::AXMode(value); | 
 |   return true; | 
 | } | 
 |  | 
 | void ParamTraits<ui::AXMode>::Log(const param_type& p, std::string* l) {} | 
 |  | 
 | void ParamTraits<scoped_refptr<storage::BlobHandle>>::Write( | 
 |     base::Pickle* m, | 
 |     const param_type& p) { | 
 |   WriteParam(m, p != nullptr); | 
 |   if (p) { | 
 |     auto info = p->Clone().PassInterface(); | 
 |     m->WriteUInt32(info.version()); | 
 |     MojoMessageHelper::WriteMessagePipeTo(m, info.PassHandle()); | 
 |   } | 
 | } | 
 |  | 
 | bool ParamTraits<scoped_refptr<storage::BlobHandle>>::Read( | 
 |     const base::Pickle* m, | 
 |     base::PickleIterator* iter, | 
 |     param_type* r) { | 
 |   bool is_not_null; | 
 |   if (!ReadParam(m, iter, &is_not_null)) | 
 |     return false; | 
 |   if (!is_not_null) | 
 |     return true; | 
 |  | 
 |   uint32_t version; | 
 |   if (!ReadParam(m, iter, &version)) | 
 |     return false; | 
 |   mojo::ScopedMessagePipeHandle handle; | 
 |   if (!MojoMessageHelper::ReadMessagePipeFrom(m, iter, &handle)) | 
 |     return false; | 
 |   DCHECK(handle.is_valid()); | 
 |   blink::mojom::BlobPtr blob; | 
 |   blob.Bind(blink::mojom::BlobPtrInfo(std::move(handle), version)); | 
 |   *r = base::MakeRefCounted<storage::BlobHandle>(std::move(blob)); | 
 |   return true; | 
 | } | 
 |  | 
 | void ParamTraits<scoped_refptr<storage::BlobHandle>>::Log(const param_type& p, | 
 |                                                           std::string* l) { | 
 |   l->append("<storage::BlobHandle>"); | 
 | } | 
 |  | 
 | // static | 
 | void ParamTraits<content::FrameMsg_ViewChanged_Params>::Write( | 
 |     base::Pickle* m, | 
 |     const param_type& p) { | 
 |   DCHECK(!features::IsAshInBrowserProcess() || | 
 |          (p.frame_sink_id.has_value() && p.frame_sink_id->is_valid())); | 
 |   WriteParam(m, p.frame_sink_id); | 
 | } | 
 |  | 
 | bool ParamTraits<content::FrameMsg_ViewChanged_Params>::Read( | 
 |     const base::Pickle* m, | 
 |     base::PickleIterator* iter, | 
 |     param_type* r) { | 
 |   if (!ReadParam(m, iter, &(r->frame_sink_id))) | 
 |     return false; | 
 |   if (features::IsAshInBrowserProcess() && | 
 |       (!r->frame_sink_id || !r->frame_sink_id->is_valid())) { | 
 |     NOTREACHED(); | 
 |     return false; | 
 |   } | 
 |   return true; | 
 | } | 
 |  | 
 | // static | 
 | void ParamTraits<content::FrameMsg_ViewChanged_Params>::Log(const param_type& p, | 
 |                                                             std::string* l) { | 
 |   l->append("("); | 
 |   LogParam(p.frame_sink_id, l); | 
 |   l->append(")"); | 
 | } | 
 |  | 
 | template <> | 
 | struct ParamTraits<blink::mojom::SerializedBlobPtr> { | 
 |   using param_type = blink::mojom::SerializedBlobPtr; | 
 |   static void Write(base::Pickle* m, const param_type& p) { | 
 |     WriteParam(m, p->uuid); | 
 |     WriteParam(m, p->content_type); | 
 |     WriteParam(m, p->size); | 
 |     WriteParam(m, p->blob.PassHandle().release()); | 
 |   } | 
 |  | 
 |   static bool Read(const base::Pickle* m, | 
 |                    base::PickleIterator* iter, | 
 |                    param_type* r) { | 
 |     *r = blink::mojom::SerializedBlob::New(); | 
 |     mojo::MessagePipeHandle handle; | 
 |     if (!ReadParam(m, iter, &(*r)->uuid) || | 
 |         !ReadParam(m, iter, &(*r)->content_type) || | 
 |         !ReadParam(m, iter, &(*r)->size) || !ReadParam(m, iter, &handle)) { | 
 |       return false; | 
 |     } | 
 |     (*r)->blob = blink::mojom::BlobPtrInfo( | 
 |         mojo::ScopedMessagePipeHandle(handle), blink::mojom::Blob::Version_); | 
 |     return true; | 
 |   } | 
 | }; | 
 |  | 
 | void ParamTraits<scoped_refptr<base::RefCountedData< | 
 |     blink::TransferableMessage>>>::Write(base::Pickle* m, const param_type& p) { | 
 |   m->WriteData(reinterpret_cast<const char*>(p->data.encoded_message.data()), | 
 |                p->data.encoded_message.size()); | 
 |   WriteParam(m, p->data.blobs); | 
 |   WriteParam(m, p->data.stack_trace_id); | 
 |   WriteParam(m, p->data.stack_trace_debugger_id_first); | 
 |   WriteParam(m, p->data.stack_trace_debugger_id_second); | 
 |   WriteParam(m, p->data.ports); | 
 |   WriteParam(m, p->data.has_user_gesture); | 
 | } | 
 |  | 
 | bool ParamTraits< | 
 |     scoped_refptr<base::RefCountedData<blink::TransferableMessage>>>:: | 
 |     Read(const base::Pickle* m, base::PickleIterator* iter, param_type* r) { | 
 |   *r = new base::RefCountedData<blink::TransferableMessage>(); | 
 |  | 
 |   const char* data; | 
 |   int length; | 
 |   if (!iter->ReadData(&data, &length)) | 
 |     return false; | 
 |   // This just makes encoded_message point into the IPC message buffer. Usually | 
 |   // code receiving a TransferableMessage will synchronously process the message | 
 |   // so this avoids an unnecessary copy. If a receiver needs to hold on to the | 
 |   // message longer, it should make sure to call EnsureDataIsOwned on the | 
 |   // returned message. | 
 |   (*r)->data.encoded_message = | 
 |       base::make_span(reinterpret_cast<const uint8_t*>(data), length); | 
 |   if (!ReadParam(m, iter, &(*r)->data.blobs) || | 
 |       !ReadParam(m, iter, &(*r)->data.stack_trace_id) || | 
 |       !ReadParam(m, iter, &(*r)->data.stack_trace_debugger_id_first) || | 
 |       !ReadParam(m, iter, &(*r)->data.stack_trace_debugger_id_second) || | 
 |       !ReadParam(m, iter, &(*r)->data.ports) || | 
 |       !ReadParam(m, iter, &(*r)->data.has_user_gesture)) { | 
 |     return false; | 
 |   } | 
 |   return true; | 
 | } | 
 |  | 
 | void ParamTraits<scoped_refptr< | 
 |     base::RefCountedData<blink::TransferableMessage>>>::Log(const param_type& p, | 
 |                                                             std::string* l) { | 
 |   l->append("<blink::TransferableMessage>"); | 
 | } | 
 |  | 
 | void ParamTraits<viz::FrameSinkId>::Write(base::Pickle* m, | 
 |                                           const param_type& p) { | 
 |   DCHECK(p.is_valid()); | 
 |   WriteParam(m, p.client_id()); | 
 |   WriteParam(m, p.sink_id()); | 
 | } | 
 |  | 
 | bool ParamTraits<viz::FrameSinkId>::Read(const base::Pickle* m, | 
 |                                          base::PickleIterator* iter, | 
 |                                          param_type* p) { | 
 |   uint32_t client_id; | 
 |   if (!ReadParam(m, iter, &client_id)) | 
 |     return false; | 
 |  | 
 |   uint32_t sink_id; | 
 |   if (!ReadParam(m, iter, &sink_id)) | 
 |     return false; | 
 |  | 
 |   *p = viz::FrameSinkId(client_id, sink_id); | 
 |   return p->is_valid(); | 
 | } | 
 |  | 
 | void ParamTraits<viz::FrameSinkId>::Log(const param_type& p, std::string* l) { | 
 |   l->append("viz::FrameSinkId("); | 
 |   LogParam(p.client_id(), l); | 
 |   l->append(", "); | 
 |   LogParam(p.sink_id(), l); | 
 |   l->append(")"); | 
 | } | 
 |  | 
 | void ParamTraits<viz::LocalSurfaceId>::Write(base::Pickle* m, | 
 |                                              const param_type& p) { | 
 |   DCHECK(p.is_valid()); | 
 |   WriteParam(m, p.parent_sequence_number()); | 
 |   WriteParam(m, p.child_sequence_number()); | 
 |   WriteParam(m, p.embed_token()); | 
 | } | 
 |  | 
 | bool ParamTraits<viz::LocalSurfaceId>::Read(const base::Pickle* m, | 
 |                                             base::PickleIterator* iter, | 
 |                                             param_type* p) { | 
 |   uint32_t parent_sequence_number; | 
 |   if (!ReadParam(m, iter, &parent_sequence_number)) | 
 |     return false; | 
 |  | 
 |   uint32_t child_sequence_number; | 
 |   if (!ReadParam(m, iter, &child_sequence_number)) | 
 |     return false; | 
 |  | 
 |   base::UnguessableToken embed_token; | 
 |   if (!ReadParam(m, iter, &embed_token)) | 
 |     return false; | 
 |  | 
 |   *p = viz::LocalSurfaceId(parent_sequence_number, child_sequence_number, | 
 |                            embed_token); | 
 |   return p->is_valid(); | 
 | } | 
 |  | 
 | void ParamTraits<viz::LocalSurfaceId>::Log(const param_type& p, | 
 |                                            std::string* l) { | 
 |   l->append("viz::LocalSurfaceId("); | 
 |   LogParam(p.parent_sequence_number(), l); | 
 |   l->append(", "); | 
 |   LogParam(p.child_sequence_number(), l); | 
 |   l->append(", "); | 
 |   LogParam(p.embed_token(), l); | 
 |   l->append(")"); | 
 | } | 
 |  | 
 | void ParamTraits<viz::SurfaceId>::Write(base::Pickle* m, const param_type& p) { | 
 |   WriteParam(m, p.frame_sink_id()); | 
 |   WriteParam(m, p.local_surface_id()); | 
 | } | 
 |  | 
 | bool ParamTraits<viz::SurfaceId>::Read(const base::Pickle* m, | 
 |                                        base::PickleIterator* iter, | 
 |                                        param_type* p) { | 
 |   viz::FrameSinkId frame_sink_id; | 
 |   if (!ReadParam(m, iter, &frame_sink_id)) | 
 |     return false; | 
 |  | 
 |   viz::LocalSurfaceId local_surface_id; | 
 |   if (!ReadParam(m, iter, &local_surface_id)) | 
 |     return false; | 
 |  | 
 |   *p = viz::SurfaceId(frame_sink_id, local_surface_id); | 
 |   return true; | 
 | } | 
 |  | 
 | void ParamTraits<viz::SurfaceId>::Log(const param_type& p, std::string* l) { | 
 |   l->append("viz::SurfaceId("); | 
 |   LogParam(p.frame_sink_id(), l); | 
 |   l->append(", "); | 
 |   LogParam(p.local_surface_id(), l); | 
 |   l->append(")"); | 
 | } | 
 |  | 
 | void ParamTraits<viz::SurfaceInfo>::Write(base::Pickle* m, | 
 |                                           const param_type& p) { | 
 |   WriteParam(m, p.id()); | 
 |   WriteParam(m, p.device_scale_factor()); | 
 |   WriteParam(m, p.size_in_pixels()); | 
 | } | 
 |  | 
 | bool ParamTraits<viz::SurfaceInfo>::Read(const base::Pickle* m, | 
 |                                          base::PickleIterator* iter, | 
 |                                          param_type* p) { | 
 |   viz::SurfaceId surface_id; | 
 |   if (!ReadParam(m, iter, &surface_id)) | 
 |     return false; | 
 |  | 
 |   float device_scale_factor; | 
 |   if (!ReadParam(m, iter, &device_scale_factor)) | 
 |     return false; | 
 |  | 
 |   gfx::Size size_in_pixels; | 
 |   if (!ReadParam(m, iter, &size_in_pixels)) | 
 |     return false; | 
 |  | 
 |   *p = viz::SurfaceInfo(surface_id, device_scale_factor, size_in_pixels); | 
 |   return p->is_valid(); | 
 | } | 
 |  | 
 | void ParamTraits<viz::SurfaceInfo>::Log(const param_type& p, std::string* l) { | 
 |   l->append("viz::SurfaceInfo("); | 
 |   LogParam(p.id(), l); | 
 |   l->append(", "); | 
 |   LogParam(p.device_scale_factor(), l); | 
 |   l->append(", "); | 
 |   LogParam(p.size_in_pixels(), l); | 
 |   l->append(")"); | 
 | } | 
 |  | 
 | }  // namespace IPC | 
 |  | 
 | // Generate param traits write methods. | 
 | #include "ipc/param_traits_write_macros.h" | 
 | namespace IPC { | 
 | #undef CONTENT_COMMON_CONTENT_PARAM_TRAITS_MACROS_H_ | 
 | #include "content/common/content_param_traits_macros.h" | 
 | }  // namespace IPC | 
 |  | 
 | // Generate param traits read methods. | 
 | #include "ipc/param_traits_read_macros.h" | 
 | namespace IPC { | 
 | #undef CONTENT_COMMON_CONTENT_PARAM_TRAITS_MACROS_H_ | 
 | #include "content/common/content_param_traits_macros.h" | 
 | }  // namespace IPC | 
 |  | 
 | // Generate param traits log methods. | 
 | #include "ipc/param_traits_log_macros.h" | 
 | namespace IPC { | 
 | #undef CONTENT_COMMON_CONTENT_PARAM_TRAITS_MACROS_H_ | 
 | #include "content/common/content_param_traits_macros.h" | 
 | }  // namespace IPC |