1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker
5*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_message_utils.h"
6*635a8641SAndroid Build Coastguard Worker
7*635a8641SAndroid Build Coastguard Worker #include <stddef.h>
8*635a8641SAndroid Build Coastguard Worker #include <stdint.h>
9*635a8641SAndroid Build Coastguard Worker
10*635a8641SAndroid Build Coastguard Worker #include "base/files/file_path.h"
11*635a8641SAndroid Build Coastguard Worker #include "base/json/json_writer.h"
12*635a8641SAndroid Build Coastguard Worker #include "base/memory/ptr_util.h"
13*635a8641SAndroid Build Coastguard Worker #include "base/strings/nullable_string16.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/strings/string_number_conversions.h"
15*635a8641SAndroid Build Coastguard Worker #include "base/strings/utf_string_conversions.h"
16*635a8641SAndroid Build Coastguard Worker #include "base/time/time.h"
17*635a8641SAndroid Build Coastguard Worker #include "base/unguessable_token.h"
18*635a8641SAndroid Build Coastguard Worker #include "base/values.h"
19*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h"
20*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_channel_handle.h"
21*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_message_attachment.h"
22*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_message_attachment_set.h"
23*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_mojo_param_traits.h"
24*635a8641SAndroid Build Coastguard Worker
25*635a8641SAndroid Build Coastguard Worker #if defined(OS_MACOSX) && !defined(OS_IOS)
26*635a8641SAndroid Build Coastguard Worker #include "ipc/mach_port_mac.h"
27*635a8641SAndroid Build Coastguard Worker #endif
28*635a8641SAndroid Build Coastguard Worker
29*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
30*635a8641SAndroid Build Coastguard Worker #include <tchar.h>
31*635a8641SAndroid Build Coastguard Worker #include "ipc/handle_win.h"
32*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_platform_file.h"
33*635a8641SAndroid Build Coastguard Worker #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
34*635a8641SAndroid Build Coastguard Worker #include "base/file_descriptor_posix.h"
35*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_platform_file_attachment_posix.h"
36*635a8641SAndroid Build Coastguard Worker #endif
37*635a8641SAndroid Build Coastguard Worker
38*635a8641SAndroid Build Coastguard Worker #if defined(OS_FUCHSIA)
39*635a8641SAndroid Build Coastguard Worker #include "ipc/handle_fuchsia.h"
40*635a8641SAndroid Build Coastguard Worker #endif
41*635a8641SAndroid Build Coastguard Worker
42*635a8641SAndroid Build Coastguard Worker #if defined(OS_ANDROID)
43*635a8641SAndroid Build Coastguard Worker #include "base/android/scoped_hardware_buffer_handle.h"
44*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_mojo_handle_attachment.h"
45*635a8641SAndroid Build Coastguard Worker #include "mojo/public/cpp/system/message_pipe.h"
46*635a8641SAndroid Build Coastguard Worker #include "mojo/public/cpp/system/scope_to_message_pipe.h"
47*635a8641SAndroid Build Coastguard Worker #endif
48*635a8641SAndroid Build Coastguard Worker
49*635a8641SAndroid Build Coastguard Worker namespace IPC {
50*635a8641SAndroid Build Coastguard Worker
51*635a8641SAndroid Build Coastguard Worker namespace {
52*635a8641SAndroid Build Coastguard Worker
53*635a8641SAndroid Build Coastguard Worker const int kMaxRecursionDepth = 200;
54*635a8641SAndroid Build Coastguard Worker
55*635a8641SAndroid Build Coastguard Worker template<typename CharType>
LogBytes(const std::vector<CharType> & data,std::string * out)56*635a8641SAndroid Build Coastguard Worker void LogBytes(const std::vector<CharType>& data, std::string* out) {
57*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
58*635a8641SAndroid Build Coastguard Worker // Windows has a GUI for logging, which can handle arbitrary binary data.
59*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < data.size(); ++i)
60*635a8641SAndroid Build Coastguard Worker out->push_back(data[i]);
61*635a8641SAndroid Build Coastguard Worker #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
62*635a8641SAndroid Build Coastguard Worker // On POSIX, we log to stdout, which we assume can display ASCII.
63*635a8641SAndroid Build Coastguard Worker static const size_t kMaxBytesToLog = 100;
64*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
65*635a8641SAndroid Build Coastguard Worker if (isprint(data[i]))
66*635a8641SAndroid Build Coastguard Worker out->push_back(data[i]);
67*635a8641SAndroid Build Coastguard Worker else
68*635a8641SAndroid Build Coastguard Worker out->append(
69*635a8641SAndroid Build Coastguard Worker base::StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
70*635a8641SAndroid Build Coastguard Worker }
71*635a8641SAndroid Build Coastguard Worker if (data.size() > kMaxBytesToLog) {
72*635a8641SAndroid Build Coastguard Worker out->append(base::StringPrintf(
73*635a8641SAndroid Build Coastguard Worker " and %u more bytes",
74*635a8641SAndroid Build Coastguard Worker static_cast<unsigned>(data.size() - kMaxBytesToLog)));
75*635a8641SAndroid Build Coastguard Worker }
76*635a8641SAndroid Build Coastguard Worker #endif
77*635a8641SAndroid Build Coastguard Worker }
78*635a8641SAndroid Build Coastguard Worker
79*635a8641SAndroid Build Coastguard Worker bool ReadValue(const base::Pickle* m,
80*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
81*635a8641SAndroid Build Coastguard Worker std::unique_ptr<base::Value>* value,
82*635a8641SAndroid Build Coastguard Worker int recursion);
83*635a8641SAndroid Build Coastguard Worker
WriteValue(base::Pickle * m,const base::Value * value,int recursion)84*635a8641SAndroid Build Coastguard Worker void WriteValue(base::Pickle* m, const base::Value* value, int recursion) {
85*635a8641SAndroid Build Coastguard Worker bool result;
86*635a8641SAndroid Build Coastguard Worker if (recursion > kMaxRecursionDepth) {
87*635a8641SAndroid Build Coastguard Worker LOG(ERROR) << "Max recursion depth hit in WriteValue.";
88*635a8641SAndroid Build Coastguard Worker return;
89*635a8641SAndroid Build Coastguard Worker }
90*635a8641SAndroid Build Coastguard Worker
91*635a8641SAndroid Build Coastguard Worker m->WriteInt(static_cast<int>(value->type()));
92*635a8641SAndroid Build Coastguard Worker
93*635a8641SAndroid Build Coastguard Worker switch (value->type()) {
94*635a8641SAndroid Build Coastguard Worker case base::Value::Type::NONE:
95*635a8641SAndroid Build Coastguard Worker break;
96*635a8641SAndroid Build Coastguard Worker case base::Value::Type::BOOLEAN: {
97*635a8641SAndroid Build Coastguard Worker bool val;
98*635a8641SAndroid Build Coastguard Worker result = value->GetAsBoolean(&val);
99*635a8641SAndroid Build Coastguard Worker DCHECK(result);
100*635a8641SAndroid Build Coastguard Worker WriteParam(m, val);
101*635a8641SAndroid Build Coastguard Worker break;
102*635a8641SAndroid Build Coastguard Worker }
103*635a8641SAndroid Build Coastguard Worker case base::Value::Type::INTEGER: {
104*635a8641SAndroid Build Coastguard Worker int val;
105*635a8641SAndroid Build Coastguard Worker result = value->GetAsInteger(&val);
106*635a8641SAndroid Build Coastguard Worker DCHECK(result);
107*635a8641SAndroid Build Coastguard Worker WriteParam(m, val);
108*635a8641SAndroid Build Coastguard Worker break;
109*635a8641SAndroid Build Coastguard Worker }
110*635a8641SAndroid Build Coastguard Worker case base::Value::Type::DOUBLE: {
111*635a8641SAndroid Build Coastguard Worker double val;
112*635a8641SAndroid Build Coastguard Worker result = value->GetAsDouble(&val);
113*635a8641SAndroid Build Coastguard Worker DCHECK(result);
114*635a8641SAndroid Build Coastguard Worker WriteParam(m, val);
115*635a8641SAndroid Build Coastguard Worker break;
116*635a8641SAndroid Build Coastguard Worker }
117*635a8641SAndroid Build Coastguard Worker case base::Value::Type::STRING: {
118*635a8641SAndroid Build Coastguard Worker std::string val;
119*635a8641SAndroid Build Coastguard Worker result = value->GetAsString(&val);
120*635a8641SAndroid Build Coastguard Worker DCHECK(result);
121*635a8641SAndroid Build Coastguard Worker WriteParam(m, val);
122*635a8641SAndroid Build Coastguard Worker break;
123*635a8641SAndroid Build Coastguard Worker }
124*635a8641SAndroid Build Coastguard Worker case base::Value::Type::BINARY: {
125*635a8641SAndroid Build Coastguard Worker m->WriteData(value->GetBlob().data(),
126*635a8641SAndroid Build Coastguard Worker base::checked_cast<int>(value->GetBlob().size()));
127*635a8641SAndroid Build Coastguard Worker break;
128*635a8641SAndroid Build Coastguard Worker }
129*635a8641SAndroid Build Coastguard Worker case base::Value::Type::DICTIONARY: {
130*635a8641SAndroid Build Coastguard Worker const base::DictionaryValue* dict =
131*635a8641SAndroid Build Coastguard Worker static_cast<const base::DictionaryValue*>(value);
132*635a8641SAndroid Build Coastguard Worker
133*635a8641SAndroid Build Coastguard Worker WriteParam(m, base::checked_cast<int>(dict->size()));
134*635a8641SAndroid Build Coastguard Worker
135*635a8641SAndroid Build Coastguard Worker for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd();
136*635a8641SAndroid Build Coastguard Worker it.Advance()) {
137*635a8641SAndroid Build Coastguard Worker WriteParam(m, it.key());
138*635a8641SAndroid Build Coastguard Worker WriteValue(m, &it.value(), recursion + 1);
139*635a8641SAndroid Build Coastguard Worker }
140*635a8641SAndroid Build Coastguard Worker break;
141*635a8641SAndroid Build Coastguard Worker }
142*635a8641SAndroid Build Coastguard Worker case base::Value::Type::LIST: {
143*635a8641SAndroid Build Coastguard Worker const base::ListValue* list = static_cast<const base::ListValue*>(value);
144*635a8641SAndroid Build Coastguard Worker WriteParam(m, base::checked_cast<int>(list->GetSize()));
145*635a8641SAndroid Build Coastguard Worker for (const auto& entry : *list) {
146*635a8641SAndroid Build Coastguard Worker WriteValue(m, &entry, recursion + 1);
147*635a8641SAndroid Build Coastguard Worker }
148*635a8641SAndroid Build Coastguard Worker break;
149*635a8641SAndroid Build Coastguard Worker }
150*635a8641SAndroid Build Coastguard Worker }
151*635a8641SAndroid Build Coastguard Worker }
152*635a8641SAndroid Build Coastguard Worker
153*635a8641SAndroid Build Coastguard Worker // Helper for ReadValue that reads a DictionaryValue into a pre-allocated
154*635a8641SAndroid Build Coastguard Worker // object.
ReadDictionaryValue(const base::Pickle * m,base::PickleIterator * iter,base::DictionaryValue * value,int recursion)155*635a8641SAndroid Build Coastguard Worker bool ReadDictionaryValue(const base::Pickle* m,
156*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
157*635a8641SAndroid Build Coastguard Worker base::DictionaryValue* value,
158*635a8641SAndroid Build Coastguard Worker int recursion) {
159*635a8641SAndroid Build Coastguard Worker int size;
160*635a8641SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &size))
161*635a8641SAndroid Build Coastguard Worker return false;
162*635a8641SAndroid Build Coastguard Worker
163*635a8641SAndroid Build Coastguard Worker for (int i = 0; i < size; ++i) {
164*635a8641SAndroid Build Coastguard Worker std::string key;
165*635a8641SAndroid Build Coastguard Worker std::unique_ptr<base::Value> subval;
166*635a8641SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &key) ||
167*635a8641SAndroid Build Coastguard Worker !ReadValue(m, iter, &subval, recursion + 1))
168*635a8641SAndroid Build Coastguard Worker return false;
169*635a8641SAndroid Build Coastguard Worker value->SetWithoutPathExpansion(key, std::move(subval));
170*635a8641SAndroid Build Coastguard Worker }
171*635a8641SAndroid Build Coastguard Worker
172*635a8641SAndroid Build Coastguard Worker return true;
173*635a8641SAndroid Build Coastguard Worker }
174*635a8641SAndroid Build Coastguard Worker
175*635a8641SAndroid Build Coastguard Worker // Helper for ReadValue that reads a ReadListValue into a pre-allocated
176*635a8641SAndroid Build Coastguard Worker // object.
ReadListValue(const base::Pickle * m,base::PickleIterator * iter,base::ListValue * value,int recursion)177*635a8641SAndroid Build Coastguard Worker bool ReadListValue(const base::Pickle* m,
178*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
179*635a8641SAndroid Build Coastguard Worker base::ListValue* value,
180*635a8641SAndroid Build Coastguard Worker int recursion) {
181*635a8641SAndroid Build Coastguard Worker int size;
182*635a8641SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &size))
183*635a8641SAndroid Build Coastguard Worker return false;
184*635a8641SAndroid Build Coastguard Worker
185*635a8641SAndroid Build Coastguard Worker for (int i = 0; i < size; ++i) {
186*635a8641SAndroid Build Coastguard Worker std::unique_ptr<base::Value> subval;
187*635a8641SAndroid Build Coastguard Worker if (!ReadValue(m, iter, &subval, recursion + 1))
188*635a8641SAndroid Build Coastguard Worker return false;
189*635a8641SAndroid Build Coastguard Worker value->Set(i, std::move(subval));
190*635a8641SAndroid Build Coastguard Worker }
191*635a8641SAndroid Build Coastguard Worker
192*635a8641SAndroid Build Coastguard Worker return true;
193*635a8641SAndroid Build Coastguard Worker }
194*635a8641SAndroid Build Coastguard Worker
ReadValue(const base::Pickle * m,base::PickleIterator * iter,std::unique_ptr<base::Value> * value,int recursion)195*635a8641SAndroid Build Coastguard Worker bool ReadValue(const base::Pickle* m,
196*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
197*635a8641SAndroid Build Coastguard Worker std::unique_ptr<base::Value>* value,
198*635a8641SAndroid Build Coastguard Worker int recursion) {
199*635a8641SAndroid Build Coastguard Worker if (recursion > kMaxRecursionDepth) {
200*635a8641SAndroid Build Coastguard Worker LOG(ERROR) << "Max recursion depth hit in ReadValue.";
201*635a8641SAndroid Build Coastguard Worker return false;
202*635a8641SAndroid Build Coastguard Worker }
203*635a8641SAndroid Build Coastguard Worker
204*635a8641SAndroid Build Coastguard Worker int type;
205*635a8641SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &type))
206*635a8641SAndroid Build Coastguard Worker return false;
207*635a8641SAndroid Build Coastguard Worker
208*635a8641SAndroid Build Coastguard Worker switch (static_cast<base::Value::Type>(type)) {
209*635a8641SAndroid Build Coastguard Worker case base::Value::Type::NONE:
210*635a8641SAndroid Build Coastguard Worker *value = std::make_unique<base::Value>();
211*635a8641SAndroid Build Coastguard Worker break;
212*635a8641SAndroid Build Coastguard Worker case base::Value::Type::BOOLEAN: {
213*635a8641SAndroid Build Coastguard Worker bool val;
214*635a8641SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &val))
215*635a8641SAndroid Build Coastguard Worker return false;
216*635a8641SAndroid Build Coastguard Worker *value = std::make_unique<base::Value>(val);
217*635a8641SAndroid Build Coastguard Worker break;
218*635a8641SAndroid Build Coastguard Worker }
219*635a8641SAndroid Build Coastguard Worker case base::Value::Type::INTEGER: {
220*635a8641SAndroid Build Coastguard Worker int val;
221*635a8641SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &val))
222*635a8641SAndroid Build Coastguard Worker return false;
223*635a8641SAndroid Build Coastguard Worker *value = std::make_unique<base::Value>(val);
224*635a8641SAndroid Build Coastguard Worker break;
225*635a8641SAndroid Build Coastguard Worker }
226*635a8641SAndroid Build Coastguard Worker case base::Value::Type::DOUBLE: {
227*635a8641SAndroid Build Coastguard Worker double val;
228*635a8641SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &val))
229*635a8641SAndroid Build Coastguard Worker return false;
230*635a8641SAndroid Build Coastguard Worker *value = std::make_unique<base::Value>(val);
231*635a8641SAndroid Build Coastguard Worker break;
232*635a8641SAndroid Build Coastguard Worker }
233*635a8641SAndroid Build Coastguard Worker case base::Value::Type::STRING: {
234*635a8641SAndroid Build Coastguard Worker std::string val;
235*635a8641SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &val))
236*635a8641SAndroid Build Coastguard Worker return false;
237*635a8641SAndroid Build Coastguard Worker *value = std::make_unique<base::Value>(std::move(val));
238*635a8641SAndroid Build Coastguard Worker break;
239*635a8641SAndroid Build Coastguard Worker }
240*635a8641SAndroid Build Coastguard Worker case base::Value::Type::BINARY: {
241*635a8641SAndroid Build Coastguard Worker const char* data;
242*635a8641SAndroid Build Coastguard Worker int length;
243*635a8641SAndroid Build Coastguard Worker if (!iter->ReadData(&data, &length))
244*635a8641SAndroid Build Coastguard Worker return false;
245*635a8641SAndroid Build Coastguard Worker *value = base::Value::CreateWithCopiedBuffer(data, length);
246*635a8641SAndroid Build Coastguard Worker break;
247*635a8641SAndroid Build Coastguard Worker }
248*635a8641SAndroid Build Coastguard Worker case base::Value::Type::DICTIONARY: {
249*635a8641SAndroid Build Coastguard Worker base::DictionaryValue val;
250*635a8641SAndroid Build Coastguard Worker if (!ReadDictionaryValue(m, iter, &val, recursion))
251*635a8641SAndroid Build Coastguard Worker return false;
252*635a8641SAndroid Build Coastguard Worker *value = std::make_unique<base::Value>(std::move(val));
253*635a8641SAndroid Build Coastguard Worker break;
254*635a8641SAndroid Build Coastguard Worker }
255*635a8641SAndroid Build Coastguard Worker case base::Value::Type::LIST: {
256*635a8641SAndroid Build Coastguard Worker base::ListValue val;
257*635a8641SAndroid Build Coastguard Worker if (!ReadListValue(m, iter, &val, recursion))
258*635a8641SAndroid Build Coastguard Worker return false;
259*635a8641SAndroid Build Coastguard Worker *value = std::make_unique<base::Value>(std::move(val));
260*635a8641SAndroid Build Coastguard Worker break;
261*635a8641SAndroid Build Coastguard Worker }
262*635a8641SAndroid Build Coastguard Worker default:
263*635a8641SAndroid Build Coastguard Worker return false;
264*635a8641SAndroid Build Coastguard Worker }
265*635a8641SAndroid Build Coastguard Worker
266*635a8641SAndroid Build Coastguard Worker return true;
267*635a8641SAndroid Build Coastguard Worker }
268*635a8641SAndroid Build Coastguard Worker
269*635a8641SAndroid Build Coastguard Worker } // namespace
270*635a8641SAndroid Build Coastguard Worker
271*635a8641SAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
272*635a8641SAndroid Build Coastguard Worker
LogData()273*635a8641SAndroid Build Coastguard Worker LogData::LogData()
274*635a8641SAndroid Build Coastguard Worker : routing_id(0),
275*635a8641SAndroid Build Coastguard Worker type(0),
276*635a8641SAndroid Build Coastguard Worker sent(0),
277*635a8641SAndroid Build Coastguard Worker receive(0),
278*635a8641SAndroid Build Coastguard Worker dispatch(0) {
279*635a8641SAndroid Build Coastguard Worker }
280*635a8641SAndroid Build Coastguard Worker
281*635a8641SAndroid Build Coastguard Worker LogData::LogData(const LogData& other) = default;
282*635a8641SAndroid Build Coastguard Worker
283*635a8641SAndroid Build Coastguard Worker LogData::~LogData() = default;
284*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)285*635a8641SAndroid Build Coastguard Worker void ParamTraits<bool>::Log(const param_type& p, std::string* l) {
286*635a8641SAndroid Build Coastguard Worker l->append(p ? "true" : "false");
287*635a8641SAndroid Build Coastguard Worker }
288*635a8641SAndroid Build Coastguard Worker
Write(base::Pickle * m,const param_type & p)289*635a8641SAndroid Build Coastguard Worker void ParamTraits<signed char>::Write(base::Pickle* m, const param_type& p) {
290*635a8641SAndroid Build Coastguard Worker m->WriteBytes(&p, sizeof(param_type));
291*635a8641SAndroid Build Coastguard Worker }
292*635a8641SAndroid Build Coastguard Worker
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)293*635a8641SAndroid Build Coastguard Worker bool ParamTraits<signed char>::Read(const base::Pickle* m,
294*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
295*635a8641SAndroid Build Coastguard Worker param_type* r) {
296*635a8641SAndroid Build Coastguard Worker const char* data;
297*635a8641SAndroid Build Coastguard Worker if (!iter->ReadBytes(&data, sizeof(param_type)))
298*635a8641SAndroid Build Coastguard Worker return false;
299*635a8641SAndroid Build Coastguard Worker memcpy(r, data, sizeof(param_type));
300*635a8641SAndroid Build Coastguard Worker return true;
301*635a8641SAndroid Build Coastguard Worker }
302*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)303*635a8641SAndroid Build Coastguard Worker void ParamTraits<signed char>::Log(const param_type& p, std::string* l) {
304*635a8641SAndroid Build Coastguard Worker l->append(base::IntToString(p));
305*635a8641SAndroid Build Coastguard Worker }
306*635a8641SAndroid Build Coastguard Worker
Write(base::Pickle * m,const param_type & p)307*635a8641SAndroid Build Coastguard Worker void ParamTraits<unsigned char>::Write(base::Pickle* m, const param_type& p) {
308*635a8641SAndroid Build Coastguard Worker m->WriteBytes(&p, sizeof(param_type));
309*635a8641SAndroid Build Coastguard Worker }
310*635a8641SAndroid Build Coastguard Worker
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)311*635a8641SAndroid Build Coastguard Worker bool ParamTraits<unsigned char>::Read(const base::Pickle* m,
312*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
313*635a8641SAndroid Build Coastguard Worker param_type* r) {
314*635a8641SAndroid Build Coastguard Worker const char* data;
315*635a8641SAndroid Build Coastguard Worker if (!iter->ReadBytes(&data, sizeof(param_type)))
316*635a8641SAndroid Build Coastguard Worker return false;
317*635a8641SAndroid Build Coastguard Worker memcpy(r, data, sizeof(param_type));
318*635a8641SAndroid Build Coastguard Worker return true;
319*635a8641SAndroid Build Coastguard Worker }
320*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)321*635a8641SAndroid Build Coastguard Worker void ParamTraits<unsigned char>::Log(const param_type& p, std::string* l) {
322*635a8641SAndroid Build Coastguard Worker l->append(base::UintToString(p));
323*635a8641SAndroid Build Coastguard Worker }
324*635a8641SAndroid Build Coastguard Worker
Write(base::Pickle * m,const param_type & p)325*635a8641SAndroid Build Coastguard Worker void ParamTraits<unsigned short>::Write(base::Pickle* m, const param_type& p) {
326*635a8641SAndroid Build Coastguard Worker m->WriteBytes(&p, sizeof(param_type));
327*635a8641SAndroid Build Coastguard Worker }
328*635a8641SAndroid Build Coastguard Worker
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)329*635a8641SAndroid Build Coastguard Worker bool ParamTraits<unsigned short>::Read(const base::Pickle* m,
330*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
331*635a8641SAndroid Build Coastguard Worker param_type* r) {
332*635a8641SAndroid Build Coastguard Worker const char* data;
333*635a8641SAndroid Build Coastguard Worker if (!iter->ReadBytes(&data, sizeof(param_type)))
334*635a8641SAndroid Build Coastguard Worker return false;
335*635a8641SAndroid Build Coastguard Worker memcpy(r, data, sizeof(param_type));
336*635a8641SAndroid Build Coastguard Worker return true;
337*635a8641SAndroid Build Coastguard Worker }
338*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)339*635a8641SAndroid Build Coastguard Worker void ParamTraits<unsigned short>::Log(const param_type& p, std::string* l) {
340*635a8641SAndroid Build Coastguard Worker l->append(base::NumberToString(p));
341*635a8641SAndroid Build Coastguard Worker }
342*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)343*635a8641SAndroid Build Coastguard Worker void ParamTraits<int>::Log(const param_type& p, std::string* l) {
344*635a8641SAndroid Build Coastguard Worker l->append(base::NumberToString(p));
345*635a8641SAndroid Build Coastguard Worker }
346*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)347*635a8641SAndroid Build Coastguard Worker void ParamTraits<unsigned int>::Log(const param_type& p, std::string* l) {
348*635a8641SAndroid Build Coastguard Worker l->append(base::NumberToString(p));
349*635a8641SAndroid Build Coastguard Worker }
350*635a8641SAndroid Build Coastguard Worker
351*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_FUCHSIA) || \
352*635a8641SAndroid Build Coastguard Worker (defined(OS_ANDROID) && defined(ARCH_CPU_64_BITS))
Log(const param_type & p,std::string * l)353*635a8641SAndroid Build Coastguard Worker void ParamTraits<long>::Log(const param_type& p, std::string* l) {
354*635a8641SAndroid Build Coastguard Worker l->append(base::NumberToString(p));
355*635a8641SAndroid Build Coastguard Worker }
356*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)357*635a8641SAndroid Build Coastguard Worker void ParamTraits<unsigned long>::Log(const param_type& p, std::string* l) {
358*635a8641SAndroid Build Coastguard Worker l->append(base::NumberToString(p));
359*635a8641SAndroid Build Coastguard Worker }
360*635a8641SAndroid Build Coastguard Worker #endif
361*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)362*635a8641SAndroid Build Coastguard Worker void ParamTraits<long long>::Log(const param_type& p, std::string* l) {
363*635a8641SAndroid Build Coastguard Worker l->append(base::NumberToString(p));
364*635a8641SAndroid Build Coastguard Worker }
365*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)366*635a8641SAndroid Build Coastguard Worker void ParamTraits<unsigned long long>::Log(const param_type& p, std::string* l) {
367*635a8641SAndroid Build Coastguard Worker l->append(base::NumberToString(p));
368*635a8641SAndroid Build Coastguard Worker }
369*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)370*635a8641SAndroid Build Coastguard Worker void ParamTraits<float>::Log(const param_type& p, std::string* l) {
371*635a8641SAndroid Build Coastguard Worker l->append(base::StringPrintf("%e", p));
372*635a8641SAndroid Build Coastguard Worker }
373*635a8641SAndroid Build Coastguard Worker
Write(base::Pickle * m,const param_type & p)374*635a8641SAndroid Build Coastguard Worker void ParamTraits<double>::Write(base::Pickle* m, const param_type& p) {
375*635a8641SAndroid Build Coastguard Worker m->WriteBytes(reinterpret_cast<const char*>(&p), sizeof(param_type));
376*635a8641SAndroid Build Coastguard Worker }
377*635a8641SAndroid Build Coastguard Worker
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)378*635a8641SAndroid Build Coastguard Worker bool ParamTraits<double>::Read(const base::Pickle* m,
379*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
380*635a8641SAndroid Build Coastguard Worker param_type* r) {
381*635a8641SAndroid Build Coastguard Worker const char *data;
382*635a8641SAndroid Build Coastguard Worker if (!iter->ReadBytes(&data, sizeof(*r))) {
383*635a8641SAndroid Build Coastguard Worker NOTREACHED();
384*635a8641SAndroid Build Coastguard Worker return false;
385*635a8641SAndroid Build Coastguard Worker }
386*635a8641SAndroid Build Coastguard Worker memcpy(r, data, sizeof(param_type));
387*635a8641SAndroid Build Coastguard Worker return true;
388*635a8641SAndroid Build Coastguard Worker }
389*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)390*635a8641SAndroid Build Coastguard Worker void ParamTraits<double>::Log(const param_type& p, std::string* l) {
391*635a8641SAndroid Build Coastguard Worker l->append(base::StringPrintf("%e", p));
392*635a8641SAndroid Build Coastguard Worker }
393*635a8641SAndroid Build Coastguard Worker
394*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)395*635a8641SAndroid Build Coastguard Worker void ParamTraits<std::string>::Log(const param_type& p, std::string* l) {
396*635a8641SAndroid Build Coastguard Worker l->append(p);
397*635a8641SAndroid Build Coastguard Worker }
398*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)399*635a8641SAndroid Build Coastguard Worker void ParamTraits<base::string16>::Log(const param_type& p, std::string* l) {
400*635a8641SAndroid Build Coastguard Worker l->append(base::UTF16ToUTF8(p));
401*635a8641SAndroid Build Coastguard Worker }
402*635a8641SAndroid Build Coastguard Worker
Write(base::Pickle * m,const param_type & p)403*635a8641SAndroid Build Coastguard Worker void ParamTraits<std::vector<char>>::Write(base::Pickle* m,
404*635a8641SAndroid Build Coastguard Worker const param_type& p) {
405*635a8641SAndroid Build Coastguard Worker if (p.empty()) {
406*635a8641SAndroid Build Coastguard Worker m->WriteData(NULL, 0);
407*635a8641SAndroid Build Coastguard Worker } else {
408*635a8641SAndroid Build Coastguard Worker m->WriteData(&p.front(), base::checked_cast<int>(p.size()));
409*635a8641SAndroid Build Coastguard Worker }
410*635a8641SAndroid Build Coastguard Worker }
411*635a8641SAndroid Build Coastguard Worker
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)412*635a8641SAndroid Build Coastguard Worker bool ParamTraits<std::vector<char>>::Read(const base::Pickle* m,
413*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
414*635a8641SAndroid Build Coastguard Worker param_type* r) {
415*635a8641SAndroid Build Coastguard Worker const char *data;
416*635a8641SAndroid Build Coastguard Worker int data_size = 0;
417*635a8641SAndroid Build Coastguard Worker if (!iter->ReadData(&data, &data_size) || data_size < 0)
418*635a8641SAndroid Build Coastguard Worker return false;
419*635a8641SAndroid Build Coastguard Worker r->resize(data_size);
420*635a8641SAndroid Build Coastguard Worker if (data_size)
421*635a8641SAndroid Build Coastguard Worker memcpy(&r->front(), data, data_size);
422*635a8641SAndroid Build Coastguard Worker return true;
423*635a8641SAndroid Build Coastguard Worker }
424*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)425*635a8641SAndroid Build Coastguard Worker void ParamTraits<std::vector<char> >::Log(const param_type& p, std::string* l) {
426*635a8641SAndroid Build Coastguard Worker LogBytes(p, l);
427*635a8641SAndroid Build Coastguard Worker }
428*635a8641SAndroid Build Coastguard Worker
Write(base::Pickle * m,const param_type & p)429*635a8641SAndroid Build Coastguard Worker void ParamTraits<std::vector<unsigned char>>::Write(base::Pickle* m,
430*635a8641SAndroid Build Coastguard Worker const param_type& p) {
431*635a8641SAndroid Build Coastguard Worker if (p.empty()) {
432*635a8641SAndroid Build Coastguard Worker m->WriteData(NULL, 0);
433*635a8641SAndroid Build Coastguard Worker } else {
434*635a8641SAndroid Build Coastguard Worker m->WriteData(reinterpret_cast<const char*>(&p.front()),
435*635a8641SAndroid Build Coastguard Worker base::checked_cast<int>(p.size()));
436*635a8641SAndroid Build Coastguard Worker }
437*635a8641SAndroid Build Coastguard Worker }
438*635a8641SAndroid Build Coastguard Worker
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)439*635a8641SAndroid Build Coastguard Worker bool ParamTraits<std::vector<unsigned char>>::Read(const base::Pickle* m,
440*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
441*635a8641SAndroid Build Coastguard Worker param_type* r) {
442*635a8641SAndroid Build Coastguard Worker const char *data;
443*635a8641SAndroid Build Coastguard Worker int data_size = 0;
444*635a8641SAndroid Build Coastguard Worker if (!iter->ReadData(&data, &data_size) || data_size < 0)
445*635a8641SAndroid Build Coastguard Worker return false;
446*635a8641SAndroid Build Coastguard Worker r->resize(data_size);
447*635a8641SAndroid Build Coastguard Worker if (data_size)
448*635a8641SAndroid Build Coastguard Worker memcpy(&r->front(), data, data_size);
449*635a8641SAndroid Build Coastguard Worker return true;
450*635a8641SAndroid Build Coastguard Worker }
451*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)452*635a8641SAndroid Build Coastguard Worker void ParamTraits<std::vector<unsigned char> >::Log(const param_type& p,
453*635a8641SAndroid Build Coastguard Worker std::string* l) {
454*635a8641SAndroid Build Coastguard Worker LogBytes(p, l);
455*635a8641SAndroid Build Coastguard Worker }
456*635a8641SAndroid Build Coastguard Worker
Write(base::Pickle * m,const param_type & p)457*635a8641SAndroid Build Coastguard Worker void ParamTraits<std::vector<bool>>::Write(base::Pickle* m,
458*635a8641SAndroid Build Coastguard Worker const param_type& p) {
459*635a8641SAndroid Build Coastguard Worker WriteParam(m, base::checked_cast<int>(p.size()));
460*635a8641SAndroid Build Coastguard Worker // Cast to bool below is required because libc++'s
461*635a8641SAndroid Build Coastguard Worker // vector<bool>::const_reference is different from bool, and we want to avoid
462*635a8641SAndroid Build Coastguard Worker // writing an extra specialization of ParamTraits for it.
463*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < p.size(); i++)
464*635a8641SAndroid Build Coastguard Worker WriteParam(m, static_cast<bool>(p[i]));
465*635a8641SAndroid Build Coastguard Worker }
466*635a8641SAndroid Build Coastguard Worker
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)467*635a8641SAndroid Build Coastguard Worker bool ParamTraits<std::vector<bool>>::Read(const base::Pickle* m,
468*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
469*635a8641SAndroid Build Coastguard Worker param_type* r) {
470*635a8641SAndroid Build Coastguard Worker int size;
471*635a8641SAndroid Build Coastguard Worker // ReadLength() checks for < 0 itself.
472*635a8641SAndroid Build Coastguard Worker if (!iter->ReadLength(&size))
473*635a8641SAndroid Build Coastguard Worker return false;
474*635a8641SAndroid Build Coastguard Worker r->resize(size);
475*635a8641SAndroid Build Coastguard Worker for (int i = 0; i < size; i++) {
476*635a8641SAndroid Build Coastguard Worker bool value;
477*635a8641SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &value))
478*635a8641SAndroid Build Coastguard Worker return false;
479*635a8641SAndroid Build Coastguard Worker (*r)[i] = value;
480*635a8641SAndroid Build Coastguard Worker }
481*635a8641SAndroid Build Coastguard Worker return true;
482*635a8641SAndroid Build Coastguard Worker }
483*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)484*635a8641SAndroid Build Coastguard Worker void ParamTraits<std::vector<bool> >::Log(const param_type& p, std::string* l) {
485*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < p.size(); ++i) {
486*635a8641SAndroid Build Coastguard Worker if (i != 0)
487*635a8641SAndroid Build Coastguard Worker l->push_back(' ');
488*635a8641SAndroid Build Coastguard Worker LogParam(static_cast<bool>(p[i]), l);
489*635a8641SAndroid Build Coastguard Worker }
490*635a8641SAndroid Build Coastguard Worker }
491*635a8641SAndroid Build Coastguard Worker
Write(base::Pickle * m,const param_type & p)492*635a8641SAndroid Build Coastguard Worker void ParamTraits<base::DictionaryValue>::Write(base::Pickle* m,
493*635a8641SAndroid Build Coastguard Worker const param_type& p) {
494*635a8641SAndroid Build Coastguard Worker WriteValue(m, &p, 0);
495*635a8641SAndroid Build Coastguard Worker }
496*635a8641SAndroid Build Coastguard Worker
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)497*635a8641SAndroid Build Coastguard Worker bool ParamTraits<base::DictionaryValue>::Read(const base::Pickle* m,
498*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
499*635a8641SAndroid Build Coastguard Worker param_type* r) {
500*635a8641SAndroid Build Coastguard Worker int type;
501*635a8641SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &type) ||
502*635a8641SAndroid Build Coastguard Worker type != static_cast<int>(base::Value::Type::DICTIONARY))
503*635a8641SAndroid Build Coastguard Worker return false;
504*635a8641SAndroid Build Coastguard Worker
505*635a8641SAndroid Build Coastguard Worker return ReadDictionaryValue(m, iter, r, 0);
506*635a8641SAndroid Build Coastguard Worker }
507*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)508*635a8641SAndroid Build Coastguard Worker void ParamTraits<base::DictionaryValue>::Log(const param_type& p,
509*635a8641SAndroid Build Coastguard Worker std::string* l) {
510*635a8641SAndroid Build Coastguard Worker std::string json;
511*635a8641SAndroid Build Coastguard Worker base::JSONWriter::Write(p, &json);
512*635a8641SAndroid Build Coastguard Worker l->append(json);
513*635a8641SAndroid Build Coastguard Worker }
514*635a8641SAndroid Build Coastguard Worker
515*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX) || defined(OS_FUCHSIA)
Write(base::Pickle * m,const param_type & p)516*635a8641SAndroid Build Coastguard Worker void ParamTraits<base::FileDescriptor>::Write(base::Pickle* m,
517*635a8641SAndroid Build Coastguard Worker const param_type& p) {
518*635a8641SAndroid Build Coastguard Worker // This serialization must be kept in sync with
519*635a8641SAndroid Build Coastguard Worker // nacl_message_scanner.cc:WriteHandle().
520*635a8641SAndroid Build Coastguard Worker const bool valid = p.fd >= 0;
521*635a8641SAndroid Build Coastguard Worker WriteParam(m, valid);
522*635a8641SAndroid Build Coastguard Worker
523*635a8641SAndroid Build Coastguard Worker if (!valid)
524*635a8641SAndroid Build Coastguard Worker return;
525*635a8641SAndroid Build Coastguard Worker
526*635a8641SAndroid Build Coastguard Worker if (p.auto_close) {
527*635a8641SAndroid Build Coastguard Worker if (!m->WriteAttachment(
528*635a8641SAndroid Build Coastguard Worker new internal::PlatformFileAttachment(base::ScopedFD(p.fd))))
529*635a8641SAndroid Build Coastguard Worker NOTREACHED();
530*635a8641SAndroid Build Coastguard Worker } else {
531*635a8641SAndroid Build Coastguard Worker if (!m->WriteAttachment(new internal::PlatformFileAttachment(p.fd)))
532*635a8641SAndroid Build Coastguard Worker NOTREACHED();
533*635a8641SAndroid Build Coastguard Worker }
534*635a8641SAndroid Build Coastguard Worker }
535*635a8641SAndroid Build Coastguard Worker
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)536*635a8641SAndroid Build Coastguard Worker bool ParamTraits<base::FileDescriptor>::Read(const base::Pickle* m,
537*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
538*635a8641SAndroid Build Coastguard Worker param_type* r) {
539*635a8641SAndroid Build Coastguard Worker *r = base::FileDescriptor();
540*635a8641SAndroid Build Coastguard Worker
541*635a8641SAndroid Build Coastguard Worker bool valid;
542*635a8641SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &valid))
543*635a8641SAndroid Build Coastguard Worker return false;
544*635a8641SAndroid Build Coastguard Worker
545*635a8641SAndroid Build Coastguard Worker if (!valid)
546*635a8641SAndroid Build Coastguard Worker return true;
547*635a8641SAndroid Build Coastguard Worker
548*635a8641SAndroid Build Coastguard Worker scoped_refptr<base::Pickle::Attachment> attachment;
549*635a8641SAndroid Build Coastguard Worker if (!m->ReadAttachment(iter, &attachment))
550*635a8641SAndroid Build Coastguard Worker return false;
551*635a8641SAndroid Build Coastguard Worker
552*635a8641SAndroid Build Coastguard Worker if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
553*635a8641SAndroid Build Coastguard Worker MessageAttachment::Type::PLATFORM_FILE) {
554*635a8641SAndroid Build Coastguard Worker return false;
555*635a8641SAndroid Build Coastguard Worker }
556*635a8641SAndroid Build Coastguard Worker
557*635a8641SAndroid Build Coastguard Worker *r = base::FileDescriptor(
558*635a8641SAndroid Build Coastguard Worker static_cast<internal::PlatformFileAttachment*>(attachment.get())
559*635a8641SAndroid Build Coastguard Worker ->TakePlatformFile(),
560*635a8641SAndroid Build Coastguard Worker true);
561*635a8641SAndroid Build Coastguard Worker return true;
562*635a8641SAndroid Build Coastguard Worker }
563*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)564*635a8641SAndroid Build Coastguard Worker void ParamTraits<base::FileDescriptor>::Log(const param_type& p,
565*635a8641SAndroid Build Coastguard Worker std::string* l) {
566*635a8641SAndroid Build Coastguard Worker if (p.auto_close) {
567*635a8641SAndroid Build Coastguard Worker l->append(base::StringPrintf("FD(%d auto-close)", p.fd));
568*635a8641SAndroid Build Coastguard Worker } else {
569*635a8641SAndroid Build Coastguard Worker l->append(base::StringPrintf("FD(%d)", p.fd));
570*635a8641SAndroid Build Coastguard Worker }
571*635a8641SAndroid Build Coastguard Worker }
572*635a8641SAndroid Build Coastguard Worker #endif // defined(OS_POSIX) || defined(OS_FUCHSIA)
573*635a8641SAndroid Build Coastguard Worker
574*635a8641SAndroid Build Coastguard Worker #if defined(OS_ANDROID)
Write(base::Pickle * m,const param_type & p)575*635a8641SAndroid Build Coastguard Worker void ParamTraits<AHardwareBuffer*>::Write(base::Pickle* m,
576*635a8641SAndroid Build Coastguard Worker const param_type& p) {
577*635a8641SAndroid Build Coastguard Worker const bool is_valid = p != nullptr;
578*635a8641SAndroid Build Coastguard Worker WriteParam(m, is_valid);
579*635a8641SAndroid Build Coastguard Worker if (!is_valid)
580*635a8641SAndroid Build Coastguard Worker return;
581*635a8641SAndroid Build Coastguard Worker
582*635a8641SAndroid Build Coastguard Worker // Assume ownership of the input AHardwareBuffer.
583*635a8641SAndroid Build Coastguard Worker auto handle = base::android::ScopedHardwareBufferHandle::Adopt(p);
584*635a8641SAndroid Build Coastguard Worker
585*635a8641SAndroid Build Coastguard Worker // We must keep a ref to the AHardwareBuffer alive until the receiver has
586*635a8641SAndroid Build Coastguard Worker // acquired its own reference. We do this by sending a message pipe handle
587*635a8641SAndroid Build Coastguard Worker // along with the buffer. When the receiver deserializes (or even if they
588*635a8641SAndroid Build Coastguard Worker // die without ever reading the message) their end of the pipe will be
589*635a8641SAndroid Build Coastguard Worker // closed. We will eventually detect this and release the AHB reference.
590*635a8641SAndroid Build Coastguard Worker mojo::MessagePipe tracking_pipe;
591*635a8641SAndroid Build Coastguard Worker m->WriteAttachment(new internal::MojoHandleAttachment(
592*635a8641SAndroid Build Coastguard Worker mojo::ScopedHandle::From(std::move(tracking_pipe.handle0))));
593*635a8641SAndroid Build Coastguard Worker WriteParam(m,
594*635a8641SAndroid Build Coastguard Worker base::FileDescriptor(handle.SerializeAsFileDescriptor().release(),
595*635a8641SAndroid Build Coastguard Worker true /* auto_close */));
596*635a8641SAndroid Build Coastguard Worker
597*635a8641SAndroid Build Coastguard Worker // Pass ownership of the input handle to our tracking pipe to keep the AHB
598*635a8641SAndroid Build Coastguard Worker // alive long enough to be deserialized by the receiver.
599*635a8641SAndroid Build Coastguard Worker mojo::ScopeToMessagePipe(std::move(handle), std::move(tracking_pipe.handle1));
600*635a8641SAndroid Build Coastguard Worker }
601*635a8641SAndroid Build Coastguard Worker
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)602*635a8641SAndroid Build Coastguard Worker bool ParamTraits<AHardwareBuffer*>::Read(const base::Pickle* m,
603*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
604*635a8641SAndroid Build Coastguard Worker param_type* r) {
605*635a8641SAndroid Build Coastguard Worker *r = nullptr;
606*635a8641SAndroid Build Coastguard Worker
607*635a8641SAndroid Build Coastguard Worker bool is_valid;
608*635a8641SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &is_valid))
609*635a8641SAndroid Build Coastguard Worker return false;
610*635a8641SAndroid Build Coastguard Worker if (!is_valid)
611*635a8641SAndroid Build Coastguard Worker return true;
612*635a8641SAndroid Build Coastguard Worker
613*635a8641SAndroid Build Coastguard Worker scoped_refptr<base::Pickle::Attachment> tracking_pipe_attachment;
614*635a8641SAndroid Build Coastguard Worker if (!m->ReadAttachment(iter, &tracking_pipe_attachment))
615*635a8641SAndroid Build Coastguard Worker return false;
616*635a8641SAndroid Build Coastguard Worker
617*635a8641SAndroid Build Coastguard Worker // We keep this alive until the AHB is safely deserialized below. When this
618*635a8641SAndroid Build Coastguard Worker // goes out of scope, the sender holding the other end of this pipe will treat
619*635a8641SAndroid Build Coastguard Worker // this handle closure as a signal that it's safe to release their AHB
620*635a8641SAndroid Build Coastguard Worker // keepalive ref.
621*635a8641SAndroid Build Coastguard Worker mojo::ScopedHandle tracking_pipe =
622*635a8641SAndroid Build Coastguard Worker static_cast<MessageAttachment*>(tracking_pipe_attachment.get())
623*635a8641SAndroid Build Coastguard Worker ->TakeMojoHandle();
624*635a8641SAndroid Build Coastguard Worker
625*635a8641SAndroid Build Coastguard Worker base::FileDescriptor descriptor;
626*635a8641SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &descriptor))
627*635a8641SAndroid Build Coastguard Worker return false;
628*635a8641SAndroid Build Coastguard Worker
629*635a8641SAndroid Build Coastguard Worker // NOTE: It is valid to deserialize an invalid FileDescriptor, so the success
630*635a8641SAndroid Build Coastguard Worker // of |ReadParam()| above does not imply that |descriptor| is valid.
631*635a8641SAndroid Build Coastguard Worker base::ScopedFD scoped_fd(descriptor.fd);
632*635a8641SAndroid Build Coastguard Worker if (!scoped_fd.is_valid())
633*635a8641SAndroid Build Coastguard Worker return false;
634*635a8641SAndroid Build Coastguard Worker
635*635a8641SAndroid Build Coastguard Worker *r = base::android::ScopedHardwareBufferHandle::DeserializeFromFileDescriptor(
636*635a8641SAndroid Build Coastguard Worker std::move(scoped_fd))
637*635a8641SAndroid Build Coastguard Worker .Take();
638*635a8641SAndroid Build Coastguard Worker return true;
639*635a8641SAndroid Build Coastguard Worker }
640*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)641*635a8641SAndroid Build Coastguard Worker void ParamTraits<AHardwareBuffer*>::Log(const param_type& p, std::string* l) {
642*635a8641SAndroid Build Coastguard Worker l->append(base::StringPrintf("AHardwareBuffer(%p)", p));
643*635a8641SAndroid Build Coastguard Worker }
644*635a8641SAndroid Build Coastguard Worker #endif // defined(OS_ANDROID)
645*635a8641SAndroid Build Coastguard Worker
Write(base::Pickle * m,const param_type & p)646*635a8641SAndroid Build Coastguard Worker void ParamTraits<base::SharedMemoryHandle>::Write(base::Pickle* m,
647*635a8641SAndroid Build Coastguard Worker const param_type& p) {
648*635a8641SAndroid Build Coastguard Worker // This serialization must be kept in sync with
649*635a8641SAndroid Build Coastguard Worker // nacl_message_scanner.cc:WriteHandle().
650*635a8641SAndroid Build Coastguard Worker const bool valid = p.IsValid();
651*635a8641SAndroid Build Coastguard Worker WriteParam(m, valid);
652*635a8641SAndroid Build Coastguard Worker
653*635a8641SAndroid Build Coastguard Worker if (!valid)
654*635a8641SAndroid Build Coastguard Worker return;
655*635a8641SAndroid Build Coastguard Worker
656*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
657*635a8641SAndroid Build Coastguard Worker HandleWin handle_win(p.GetHandle());
658*635a8641SAndroid Build Coastguard Worker WriteParam(m, handle_win);
659*635a8641SAndroid Build Coastguard Worker #elif defined(OS_FUCHSIA)
660*635a8641SAndroid Build Coastguard Worker HandleFuchsia handle_fuchsia(p.GetHandle());
661*635a8641SAndroid Build Coastguard Worker WriteParam(m, handle_fuchsia);
662*635a8641SAndroid Build Coastguard Worker #elif defined(OS_MACOSX) && !defined(OS_IOS)
663*635a8641SAndroid Build Coastguard Worker MachPortMac mach_port_mac(p.GetMemoryObject());
664*635a8641SAndroid Build Coastguard Worker WriteParam(m, mach_port_mac);
665*635a8641SAndroid Build Coastguard Worker #elif defined(OS_POSIX)
666*635a8641SAndroid Build Coastguard Worker #if defined(OS_ANDROID)
667*635a8641SAndroid Build Coastguard Worker WriteParam(m, p.IsReadOnly());
668*635a8641SAndroid Build Coastguard Worker
669*635a8641SAndroid Build Coastguard Worker // Ensure the region is read-only before sending it through IPC.
670*635a8641SAndroid Build Coastguard Worker if (p.IsReadOnly()) {
671*635a8641SAndroid Build Coastguard Worker if (!p.IsRegionReadOnly()) {
672*635a8641SAndroid Build Coastguard Worker LOG(ERROR) << "Sending unsealed read-only region through IPC";
673*635a8641SAndroid Build Coastguard Worker p.SetRegionReadOnly();
674*635a8641SAndroid Build Coastguard Worker }
675*635a8641SAndroid Build Coastguard Worker }
676*635a8641SAndroid Build Coastguard Worker #endif
677*635a8641SAndroid Build Coastguard Worker if (p.OwnershipPassesToIPC()) {
678*635a8641SAndroid Build Coastguard Worker if (!m->WriteAttachment(new internal::PlatformFileAttachment(
679*635a8641SAndroid Build Coastguard Worker base::ScopedFD(p.GetHandle()))))
680*635a8641SAndroid Build Coastguard Worker NOTREACHED();
681*635a8641SAndroid Build Coastguard Worker } else {
682*635a8641SAndroid Build Coastguard Worker if (!m->WriteAttachment(
683*635a8641SAndroid Build Coastguard Worker new internal::PlatformFileAttachment(p.GetHandle())))
684*635a8641SAndroid Build Coastguard Worker NOTREACHED();
685*635a8641SAndroid Build Coastguard Worker }
686*635a8641SAndroid Build Coastguard Worker #endif
687*635a8641SAndroid Build Coastguard Worker
688*635a8641SAndroid Build Coastguard Worker #if (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN)
689*635a8641SAndroid Build Coastguard Worker // If the caller intended to pass ownership to the IPC stack, release a
690*635a8641SAndroid Build Coastguard Worker // reference.
691*635a8641SAndroid Build Coastguard Worker if (p.OwnershipPassesToIPC())
692*635a8641SAndroid Build Coastguard Worker p.Close();
693*635a8641SAndroid Build Coastguard Worker #endif
694*635a8641SAndroid Build Coastguard Worker
695*635a8641SAndroid Build Coastguard Worker DCHECK(!p.GetGUID().is_empty());
696*635a8641SAndroid Build Coastguard Worker WriteParam(m, p.GetGUID());
697*635a8641SAndroid Build Coastguard Worker WriteParam(m, static_cast<uint64_t>(p.GetSize()));
698*635a8641SAndroid Build Coastguard Worker }
699*635a8641SAndroid Build Coastguard Worker
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)700*635a8641SAndroid Build Coastguard Worker bool ParamTraits<base::SharedMemoryHandle>::Read(const base::Pickle* m,
701*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
702*635a8641SAndroid Build Coastguard Worker param_type* r) {
703*635a8641SAndroid Build Coastguard Worker *r = base::SharedMemoryHandle();
704*635a8641SAndroid Build Coastguard Worker
705*635a8641SAndroid Build Coastguard Worker bool valid;
706*635a8641SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &valid))
707*635a8641SAndroid Build Coastguard Worker return false;
708*635a8641SAndroid Build Coastguard Worker if (!valid)
709*635a8641SAndroid Build Coastguard Worker return true;
710*635a8641SAndroid Build Coastguard Worker
711*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
712*635a8641SAndroid Build Coastguard Worker HandleWin handle_win;
713*635a8641SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &handle_win))
714*635a8641SAndroid Build Coastguard Worker return false;
715*635a8641SAndroid Build Coastguard Worker #elif defined(OS_FUCHSIA)
716*635a8641SAndroid Build Coastguard Worker HandleFuchsia handle_fuchsia;
717*635a8641SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &handle_fuchsia))
718*635a8641SAndroid Build Coastguard Worker return false;
719*635a8641SAndroid Build Coastguard Worker #elif defined(OS_MACOSX) && !defined(OS_IOS)
720*635a8641SAndroid Build Coastguard Worker MachPortMac mach_port_mac;
721*635a8641SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &mach_port_mac))
722*635a8641SAndroid Build Coastguard Worker return false;
723*635a8641SAndroid Build Coastguard Worker #elif defined(OS_POSIX)
724*635a8641SAndroid Build Coastguard Worker #if defined(OS_ANDROID)
725*635a8641SAndroid Build Coastguard Worker bool is_read_only = false;
726*635a8641SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &is_read_only))
727*635a8641SAndroid Build Coastguard Worker return false;
728*635a8641SAndroid Build Coastguard Worker #endif
729*635a8641SAndroid Build Coastguard Worker scoped_refptr<base::Pickle::Attachment> attachment;
730*635a8641SAndroid Build Coastguard Worker if (!m->ReadAttachment(iter, &attachment))
731*635a8641SAndroid Build Coastguard Worker return false;
732*635a8641SAndroid Build Coastguard Worker
733*635a8641SAndroid Build Coastguard Worker if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
734*635a8641SAndroid Build Coastguard Worker MessageAttachment::Type::PLATFORM_FILE) {
735*635a8641SAndroid Build Coastguard Worker return false;
736*635a8641SAndroid Build Coastguard Worker }
737*635a8641SAndroid Build Coastguard Worker #endif
738*635a8641SAndroid Build Coastguard Worker
739*635a8641SAndroid Build Coastguard Worker base::UnguessableToken guid;
740*635a8641SAndroid Build Coastguard Worker uint64_t size;
741*635a8641SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &guid) || !ReadParam(m, iter, &size) ||
742*635a8641SAndroid Build Coastguard Worker !base::IsValueInRangeForNumericType<size_t>(size)) {
743*635a8641SAndroid Build Coastguard Worker return false;
744*635a8641SAndroid Build Coastguard Worker }
745*635a8641SAndroid Build Coastguard Worker
746*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
747*635a8641SAndroid Build Coastguard Worker *r = base::SharedMemoryHandle(handle_win.get_handle(),
748*635a8641SAndroid Build Coastguard Worker static_cast<size_t>(size), guid);
749*635a8641SAndroid Build Coastguard Worker #elif defined(OS_FUCHSIA)
750*635a8641SAndroid Build Coastguard Worker *r = base::SharedMemoryHandle(handle_fuchsia.get_handle(),
751*635a8641SAndroid Build Coastguard Worker static_cast<size_t>(size), guid);
752*635a8641SAndroid Build Coastguard Worker #elif defined(OS_MACOSX) && !defined(OS_IOS)
753*635a8641SAndroid Build Coastguard Worker *r = base::SharedMemoryHandle(mach_port_mac.get_mach_port(),
754*635a8641SAndroid Build Coastguard Worker static_cast<size_t>(size), guid);
755*635a8641SAndroid Build Coastguard Worker #elif defined(OS_POSIX)
756*635a8641SAndroid Build Coastguard Worker *r = base::SharedMemoryHandle(
757*635a8641SAndroid Build Coastguard Worker base::FileDescriptor(
758*635a8641SAndroid Build Coastguard Worker static_cast<internal::PlatformFileAttachment*>(attachment.get())
759*635a8641SAndroid Build Coastguard Worker ->TakePlatformFile(),
760*635a8641SAndroid Build Coastguard Worker true),
761*635a8641SAndroid Build Coastguard Worker static_cast<size_t>(size), guid);
762*635a8641SAndroid Build Coastguard Worker #endif
763*635a8641SAndroid Build Coastguard Worker
764*635a8641SAndroid Build Coastguard Worker #if defined(OS_ANDROID)
765*635a8641SAndroid Build Coastguard Worker if (is_read_only)
766*635a8641SAndroid Build Coastguard Worker r->SetReadOnly();
767*635a8641SAndroid Build Coastguard Worker #endif
768*635a8641SAndroid Build Coastguard Worker
769*635a8641SAndroid Build Coastguard Worker return true;
770*635a8641SAndroid Build Coastguard Worker }
771*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)772*635a8641SAndroid Build Coastguard Worker void ParamTraits<base::SharedMemoryHandle>::Log(const param_type& p,
773*635a8641SAndroid Build Coastguard Worker std::string* l) {
774*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
775*635a8641SAndroid Build Coastguard Worker l->append("HANDLE: ");
776*635a8641SAndroid Build Coastguard Worker LogParam(p.GetHandle(), l);
777*635a8641SAndroid Build Coastguard Worker #elif defined(OS_MACOSX) && !defined(OS_IOS)
778*635a8641SAndroid Build Coastguard Worker l->append("Mach port: ");
779*635a8641SAndroid Build Coastguard Worker LogParam(p.GetMemoryObject(), l);
780*635a8641SAndroid Build Coastguard Worker #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
781*635a8641SAndroid Build Coastguard Worker l->append("FD: ");
782*635a8641SAndroid Build Coastguard Worker LogParam(p.GetHandle(), l);
783*635a8641SAndroid Build Coastguard Worker #endif
784*635a8641SAndroid Build Coastguard Worker
785*635a8641SAndroid Build Coastguard Worker l->append("GUID: ");
786*635a8641SAndroid Build Coastguard Worker LogParam(p.GetGUID(), l);
787*635a8641SAndroid Build Coastguard Worker l->append("size: ");
788*635a8641SAndroid Build Coastguard Worker LogParam(static_cast<uint64_t>(p.GetSize()), l);
789*635a8641SAndroid Build Coastguard Worker #if defined(OS_ANDROID)
790*635a8641SAndroid Build Coastguard Worker l->append("read-only: ");
791*635a8641SAndroid Build Coastguard Worker LogParam(p.IsReadOnly(), l);
792*635a8641SAndroid Build Coastguard Worker #endif
793*635a8641SAndroid Build Coastguard Worker }
794*635a8641SAndroid Build Coastguard Worker
Write(base::Pickle * m,const param_type & p)795*635a8641SAndroid Build Coastguard Worker void ParamTraits<base::ReadOnlySharedMemoryRegion>::Write(base::Pickle* m,
796*635a8641SAndroid Build Coastguard Worker const param_type& p) {
797*635a8641SAndroid Build Coastguard Worker base::subtle::PlatformSharedMemoryRegion handle =
798*635a8641SAndroid Build Coastguard Worker base::ReadOnlySharedMemoryRegion::TakeHandleForSerialization(
799*635a8641SAndroid Build Coastguard Worker std::move(const_cast<param_type&>(p)));
800*635a8641SAndroid Build Coastguard Worker WriteParam(m, std::move(handle));
801*635a8641SAndroid Build Coastguard Worker }
802*635a8641SAndroid Build Coastguard Worker
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)803*635a8641SAndroid Build Coastguard Worker bool ParamTraits<base::ReadOnlySharedMemoryRegion>::Read(
804*635a8641SAndroid Build Coastguard Worker const base::Pickle* m,
805*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
806*635a8641SAndroid Build Coastguard Worker param_type* r) {
807*635a8641SAndroid Build Coastguard Worker base::subtle::PlatformSharedMemoryRegion handle;
808*635a8641SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &handle))
809*635a8641SAndroid Build Coastguard Worker return false;
810*635a8641SAndroid Build Coastguard Worker
811*635a8641SAndroid Build Coastguard Worker *r = base::ReadOnlySharedMemoryRegion::Deserialize(std::move(handle));
812*635a8641SAndroid Build Coastguard Worker return true;
813*635a8641SAndroid Build Coastguard Worker }
814*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)815*635a8641SAndroid Build Coastguard Worker void ParamTraits<base::ReadOnlySharedMemoryRegion>::Log(const param_type& p,
816*635a8641SAndroid Build Coastguard Worker std::string* l) {
817*635a8641SAndroid Build Coastguard Worker *l = "<base::ReadOnlySharedMemoryRegion>";
818*635a8641SAndroid Build Coastguard Worker // TODO(alexilin): currently there is no way to access underlying handle
819*635a8641SAndroid Build Coastguard Worker // without destructing a ReadOnlySharedMemoryRegion instance.
820*635a8641SAndroid Build Coastguard Worker }
821*635a8641SAndroid Build Coastguard Worker
Write(base::Pickle * m,const param_type & p)822*635a8641SAndroid Build Coastguard Worker void ParamTraits<base::WritableSharedMemoryRegion>::Write(base::Pickle* m,
823*635a8641SAndroid Build Coastguard Worker const param_type& p) {
824*635a8641SAndroid Build Coastguard Worker base::subtle::PlatformSharedMemoryRegion handle =
825*635a8641SAndroid Build Coastguard Worker base::WritableSharedMemoryRegion::TakeHandleForSerialization(
826*635a8641SAndroid Build Coastguard Worker std::move(const_cast<param_type&>(p)));
827*635a8641SAndroid Build Coastguard Worker WriteParam(m, std::move(handle));
828*635a8641SAndroid Build Coastguard Worker }
829*635a8641SAndroid Build Coastguard Worker
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)830*635a8641SAndroid Build Coastguard Worker bool ParamTraits<base::WritableSharedMemoryRegion>::Read(
831*635a8641SAndroid Build Coastguard Worker const base::Pickle* m,
832*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
833*635a8641SAndroid Build Coastguard Worker param_type* r) {
834*635a8641SAndroid Build Coastguard Worker base::subtle::PlatformSharedMemoryRegion handle;
835*635a8641SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &handle))
836*635a8641SAndroid Build Coastguard Worker return false;
837*635a8641SAndroid Build Coastguard Worker
838*635a8641SAndroid Build Coastguard Worker *r = base::WritableSharedMemoryRegion::Deserialize(std::move(handle));
839*635a8641SAndroid Build Coastguard Worker return true;
840*635a8641SAndroid Build Coastguard Worker }
841*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)842*635a8641SAndroid Build Coastguard Worker void ParamTraits<base::WritableSharedMemoryRegion>::Log(const param_type& p,
843*635a8641SAndroid Build Coastguard Worker std::string* l) {
844*635a8641SAndroid Build Coastguard Worker *l = "<base::WritableSharedMemoryRegion>";
845*635a8641SAndroid Build Coastguard Worker // TODO(alexilin): currently there is no way to access underlying handle
846*635a8641SAndroid Build Coastguard Worker // without destructing a ReadOnlySharedMemoryRegion instance.
847*635a8641SAndroid Build Coastguard Worker }
848*635a8641SAndroid Build Coastguard Worker
Write(base::Pickle * m,const param_type & p)849*635a8641SAndroid Build Coastguard Worker void ParamTraits<base::UnsafeSharedMemoryRegion>::Write(base::Pickle* m,
850*635a8641SAndroid Build Coastguard Worker const param_type& p) {
851*635a8641SAndroid Build Coastguard Worker base::subtle::PlatformSharedMemoryRegion handle =
852*635a8641SAndroid Build Coastguard Worker base::UnsafeSharedMemoryRegion::TakeHandleForSerialization(
853*635a8641SAndroid Build Coastguard Worker std::move(const_cast<param_type&>(p)));
854*635a8641SAndroid Build Coastguard Worker WriteParam(m, std::move(handle));
855*635a8641SAndroid Build Coastguard Worker }
856*635a8641SAndroid Build Coastguard Worker
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)857*635a8641SAndroid Build Coastguard Worker bool ParamTraits<base::UnsafeSharedMemoryRegion>::Read(
858*635a8641SAndroid Build Coastguard Worker const base::Pickle* m,
859*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
860*635a8641SAndroid Build Coastguard Worker param_type* r) {
861*635a8641SAndroid Build Coastguard Worker base::subtle::PlatformSharedMemoryRegion handle;
862*635a8641SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &handle))
863*635a8641SAndroid Build Coastguard Worker return false;
864*635a8641SAndroid Build Coastguard Worker
865*635a8641SAndroid Build Coastguard Worker *r = base::UnsafeSharedMemoryRegion::Deserialize(std::move(handle));
866*635a8641SAndroid Build Coastguard Worker return true;
867*635a8641SAndroid Build Coastguard Worker }
868*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)869*635a8641SAndroid Build Coastguard Worker void ParamTraits<base::UnsafeSharedMemoryRegion>::Log(const param_type& p,
870*635a8641SAndroid Build Coastguard Worker std::string* l) {
871*635a8641SAndroid Build Coastguard Worker *l = "<base::UnsafeSharedMemoryRegion>";
872*635a8641SAndroid Build Coastguard Worker // TODO(alexilin): currently there is no way to access underlying handle
873*635a8641SAndroid Build Coastguard Worker // without destructing a ReadOnlySharedMemoryRegion instance.
874*635a8641SAndroid Build Coastguard Worker }
875*635a8641SAndroid Build Coastguard Worker
Write(base::Pickle * m,const param_type & p)876*635a8641SAndroid Build Coastguard Worker void ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Write(
877*635a8641SAndroid Build Coastguard Worker base::Pickle* m,
878*635a8641SAndroid Build Coastguard Worker const param_type& p) {
879*635a8641SAndroid Build Coastguard Worker // This serialization must be kept in sync with
880*635a8641SAndroid Build Coastguard Worker // nacl_message_scanner.cc::WriteHandle().
881*635a8641SAndroid Build Coastguard Worker const bool valid = p.IsValid();
882*635a8641SAndroid Build Coastguard Worker WriteParam(m, valid);
883*635a8641SAndroid Build Coastguard Worker
884*635a8641SAndroid Build Coastguard Worker if (!valid)
885*635a8641SAndroid Build Coastguard Worker return;
886*635a8641SAndroid Build Coastguard Worker
887*635a8641SAndroid Build Coastguard Worker WriteParam(m, p.GetMode());
888*635a8641SAndroid Build Coastguard Worker WriteParam(m, static_cast<uint64_t>(p.GetSize()));
889*635a8641SAndroid Build Coastguard Worker WriteParam(m, p.GetGUID());
890*635a8641SAndroid Build Coastguard Worker
891*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
892*635a8641SAndroid Build Coastguard Worker base::win::ScopedHandle h = const_cast<param_type&>(p).PassPlatformHandle();
893*635a8641SAndroid Build Coastguard Worker HandleWin handle_win(h.Take());
894*635a8641SAndroid Build Coastguard Worker WriteParam(m, handle_win);
895*635a8641SAndroid Build Coastguard Worker #elif defined(OS_FUCHSIA)
896*635a8641SAndroid Build Coastguard Worker zx::handle h = const_cast<param_type&>(p).PassPlatformHandle();
897*635a8641SAndroid Build Coastguard Worker HandleFuchsia handle_fuchsia(h.release());
898*635a8641SAndroid Build Coastguard Worker WriteParam(m, handle_fuchsia);
899*635a8641SAndroid Build Coastguard Worker #elif defined(OS_MACOSX) && !defined(OS_IOS)
900*635a8641SAndroid Build Coastguard Worker base::mac::ScopedMachSendRight h =
901*635a8641SAndroid Build Coastguard Worker const_cast<param_type&>(p).PassPlatformHandle();
902*635a8641SAndroid Build Coastguard Worker MachPortMac mach_port_mac(h.release());
903*635a8641SAndroid Build Coastguard Worker WriteParam(m, mach_port_mac);
904*635a8641SAndroid Build Coastguard Worker #elif defined(OS_ANDROID)
905*635a8641SAndroid Build Coastguard Worker m->WriteAttachment(new internal::PlatformFileAttachment(
906*635a8641SAndroid Build Coastguard Worker base::ScopedFD(const_cast<param_type&>(p).PassPlatformHandle())));
907*635a8641SAndroid Build Coastguard Worker #elif defined(OS_POSIX)
908*635a8641SAndroid Build Coastguard Worker base::subtle::ScopedFDPair h =
909*635a8641SAndroid Build Coastguard Worker const_cast<param_type&>(p).PassPlatformHandle();
910*635a8641SAndroid Build Coastguard Worker m->WriteAttachment(new internal::PlatformFileAttachment(std::move(h.fd)));
911*635a8641SAndroid Build Coastguard Worker if (p.GetMode() ==
912*635a8641SAndroid Build Coastguard Worker base::subtle::PlatformSharedMemoryRegion::Mode::kWritable) {
913*635a8641SAndroid Build Coastguard Worker m->WriteAttachment(
914*635a8641SAndroid Build Coastguard Worker new internal::PlatformFileAttachment(std::move(h.readonly_fd)));
915*635a8641SAndroid Build Coastguard Worker }
916*635a8641SAndroid Build Coastguard Worker #endif
917*635a8641SAndroid Build Coastguard Worker }
918*635a8641SAndroid Build Coastguard Worker
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)919*635a8641SAndroid Build Coastguard Worker bool ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Read(
920*635a8641SAndroid Build Coastguard Worker const base::Pickle* m,
921*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
922*635a8641SAndroid Build Coastguard Worker param_type* r) {
923*635a8641SAndroid Build Coastguard Worker bool valid;
924*635a8641SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &valid))
925*635a8641SAndroid Build Coastguard Worker return false;
926*635a8641SAndroid Build Coastguard Worker if (!valid) {
927*635a8641SAndroid Build Coastguard Worker *r = base::subtle::PlatformSharedMemoryRegion();
928*635a8641SAndroid Build Coastguard Worker return true;
929*635a8641SAndroid Build Coastguard Worker }
930*635a8641SAndroid Build Coastguard Worker
931*635a8641SAndroid Build Coastguard Worker base::subtle::PlatformSharedMemoryRegion::Mode mode;
932*635a8641SAndroid Build Coastguard Worker uint64_t shm_size;
933*635a8641SAndroid Build Coastguard Worker base::UnguessableToken guid;
934*635a8641SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &mode) || !ReadParam(m, iter, &shm_size) ||
935*635a8641SAndroid Build Coastguard Worker !base::IsValueInRangeForNumericType<size_t>(shm_size) ||
936*635a8641SAndroid Build Coastguard Worker !ReadParam(m, iter, &guid)) {
937*635a8641SAndroid Build Coastguard Worker return false;
938*635a8641SAndroid Build Coastguard Worker }
939*635a8641SAndroid Build Coastguard Worker size_t size = static_cast<size_t>(shm_size);
940*635a8641SAndroid Build Coastguard Worker
941*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
942*635a8641SAndroid Build Coastguard Worker HandleWin handle_win;
943*635a8641SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &handle_win))
944*635a8641SAndroid Build Coastguard Worker return false;
945*635a8641SAndroid Build Coastguard Worker *r = base::subtle::PlatformSharedMemoryRegion::Take(
946*635a8641SAndroid Build Coastguard Worker base::win::ScopedHandle(handle_win.get_handle()), mode, size, guid);
947*635a8641SAndroid Build Coastguard Worker #elif defined(OS_FUCHSIA)
948*635a8641SAndroid Build Coastguard Worker HandleFuchsia handle_fuchsia;
949*635a8641SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &handle_fuchsia))
950*635a8641SAndroid Build Coastguard Worker return false;
951*635a8641SAndroid Build Coastguard Worker *r = base::subtle::PlatformSharedMemoryRegion::Take(
952*635a8641SAndroid Build Coastguard Worker zx::vmo(handle_fuchsia.get_handle()), mode, size, guid);
953*635a8641SAndroid Build Coastguard Worker #elif defined(OS_MACOSX) && !defined(OS_IOS)
954*635a8641SAndroid Build Coastguard Worker MachPortMac mach_port_mac;
955*635a8641SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &mach_port_mac))
956*635a8641SAndroid Build Coastguard Worker return false;
957*635a8641SAndroid Build Coastguard Worker *r = base::subtle::PlatformSharedMemoryRegion::Take(
958*635a8641SAndroid Build Coastguard Worker base::mac::ScopedMachSendRight(mach_port_mac.get_mach_port()), mode, size,
959*635a8641SAndroid Build Coastguard Worker guid);
960*635a8641SAndroid Build Coastguard Worker #elif defined(OS_POSIX)
961*635a8641SAndroid Build Coastguard Worker scoped_refptr<base::Pickle::Attachment> attachment;
962*635a8641SAndroid Build Coastguard Worker if (!m->ReadAttachment(iter, &attachment))
963*635a8641SAndroid Build Coastguard Worker return false;
964*635a8641SAndroid Build Coastguard Worker if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
965*635a8641SAndroid Build Coastguard Worker MessageAttachment::Type::PLATFORM_FILE) {
966*635a8641SAndroid Build Coastguard Worker return false;
967*635a8641SAndroid Build Coastguard Worker }
968*635a8641SAndroid Build Coastguard Worker
969*635a8641SAndroid Build Coastguard Worker #if defined(OS_ANDROID)
970*635a8641SAndroid Build Coastguard Worker *r = base::subtle::PlatformSharedMemoryRegion::Take(
971*635a8641SAndroid Build Coastguard Worker base::ScopedFD(
972*635a8641SAndroid Build Coastguard Worker static_cast<internal::PlatformFileAttachment*>(attachment.get())
973*635a8641SAndroid Build Coastguard Worker ->TakePlatformFile()),
974*635a8641SAndroid Build Coastguard Worker mode, size, guid);
975*635a8641SAndroid Build Coastguard Worker #else
976*635a8641SAndroid Build Coastguard Worker scoped_refptr<base::Pickle::Attachment> readonly_attachment;
977*635a8641SAndroid Build Coastguard Worker if (mode == base::subtle::PlatformSharedMemoryRegion::Mode::kWritable) {
978*635a8641SAndroid Build Coastguard Worker if (!m->ReadAttachment(iter, &readonly_attachment))
979*635a8641SAndroid Build Coastguard Worker return false;
980*635a8641SAndroid Build Coastguard Worker
981*635a8641SAndroid Build Coastguard Worker if (static_cast<MessageAttachment*>(readonly_attachment.get())->GetType() !=
982*635a8641SAndroid Build Coastguard Worker MessageAttachment::Type::PLATFORM_FILE) {
983*635a8641SAndroid Build Coastguard Worker return false;
984*635a8641SAndroid Build Coastguard Worker }
985*635a8641SAndroid Build Coastguard Worker }
986*635a8641SAndroid Build Coastguard Worker *r = base::subtle::PlatformSharedMemoryRegion::Take(
987*635a8641SAndroid Build Coastguard Worker base::subtle::ScopedFDPair(
988*635a8641SAndroid Build Coastguard Worker base::ScopedFD(
989*635a8641SAndroid Build Coastguard Worker static_cast<internal::PlatformFileAttachment*>(attachment.get())
990*635a8641SAndroid Build Coastguard Worker ->TakePlatformFile()),
991*635a8641SAndroid Build Coastguard Worker readonly_attachment
992*635a8641SAndroid Build Coastguard Worker ? base::ScopedFD(static_cast<internal::PlatformFileAttachment*>(
993*635a8641SAndroid Build Coastguard Worker readonly_attachment.get())
994*635a8641SAndroid Build Coastguard Worker ->TakePlatformFile())
995*635a8641SAndroid Build Coastguard Worker : base::ScopedFD()),
996*635a8641SAndroid Build Coastguard Worker mode, size, guid);
997*635a8641SAndroid Build Coastguard Worker #endif // defined(OS_ANDROID)
998*635a8641SAndroid Build Coastguard Worker
999*635a8641SAndroid Build Coastguard Worker #endif
1000*635a8641SAndroid Build Coastguard Worker
1001*635a8641SAndroid Build Coastguard Worker return true;
1002*635a8641SAndroid Build Coastguard Worker }
1003*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)1004*635a8641SAndroid Build Coastguard Worker void ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Log(
1005*635a8641SAndroid Build Coastguard Worker const param_type& p,
1006*635a8641SAndroid Build Coastguard Worker std::string* l) {
1007*635a8641SAndroid Build Coastguard Worker #if defined(OS_FUCHSIA) || defined(OS_WIN)
1008*635a8641SAndroid Build Coastguard Worker l->append("Handle: ");
1009*635a8641SAndroid Build Coastguard Worker LogParam(p.GetPlatformHandle(), l);
1010*635a8641SAndroid Build Coastguard Worker #elif defined(OS_MACOSX) && !defined(OS_IOS)
1011*635a8641SAndroid Build Coastguard Worker l->append("Mach port: ");
1012*635a8641SAndroid Build Coastguard Worker LogParam(p.GetPlatformHandle(), l);
1013*635a8641SAndroid Build Coastguard Worker #elif defined(OS_ANDROID)
1014*635a8641SAndroid Build Coastguard Worker l->append("FD: ");
1015*635a8641SAndroid Build Coastguard Worker LogParam(p.GetPlatformHandle(), l);
1016*635a8641SAndroid Build Coastguard Worker #elif defined(OS_POSIX)
1017*635a8641SAndroid Build Coastguard Worker base::subtle::FDPair h = p.GetPlatformHandle();
1018*635a8641SAndroid Build Coastguard Worker l->append("FD: ");
1019*635a8641SAndroid Build Coastguard Worker LogParam(h.fd, l);
1020*635a8641SAndroid Build Coastguard Worker l->append("Read-only FD: ");
1021*635a8641SAndroid Build Coastguard Worker LogParam(h.readonly_fd, l);
1022*635a8641SAndroid Build Coastguard Worker #endif
1023*635a8641SAndroid Build Coastguard Worker
1024*635a8641SAndroid Build Coastguard Worker l->append("Mode: ");
1025*635a8641SAndroid Build Coastguard Worker LogParam(p.GetMode(), l);
1026*635a8641SAndroid Build Coastguard Worker l->append("size: ");
1027*635a8641SAndroid Build Coastguard Worker LogParam(static_cast<uint64_t>(p.GetSize()), l);
1028*635a8641SAndroid Build Coastguard Worker l->append("GUID: ");
1029*635a8641SAndroid Build Coastguard Worker LogParam(p.GetGUID(), l);
1030*635a8641SAndroid Build Coastguard Worker }
1031*635a8641SAndroid Build Coastguard Worker
Write(base::Pickle * m,const param_type & value)1032*635a8641SAndroid Build Coastguard Worker void ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Write(
1033*635a8641SAndroid Build Coastguard Worker base::Pickle* m,
1034*635a8641SAndroid Build Coastguard Worker const param_type& value) {
1035*635a8641SAndroid Build Coastguard Worker DCHECK(static_cast<int>(value) >= 0 &&
1036*635a8641SAndroid Build Coastguard Worker static_cast<int>(value) <= static_cast<int>(param_type::kMaxValue));
1037*635a8641SAndroid Build Coastguard Worker m->WriteInt(static_cast<int>(value));
1038*635a8641SAndroid Build Coastguard Worker }
1039*635a8641SAndroid Build Coastguard Worker
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * p)1040*635a8641SAndroid Build Coastguard Worker bool ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Read(
1041*635a8641SAndroid Build Coastguard Worker const base::Pickle* m,
1042*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
1043*635a8641SAndroid Build Coastguard Worker param_type* p) {
1044*635a8641SAndroid Build Coastguard Worker int value;
1045*635a8641SAndroid Build Coastguard Worker if (!iter->ReadInt(&value))
1046*635a8641SAndroid Build Coastguard Worker return false;
1047*635a8641SAndroid Build Coastguard Worker if (!(static_cast<int>(value) >= 0 &&
1048*635a8641SAndroid Build Coastguard Worker static_cast<int>(value) <= static_cast<int>(param_type::kMaxValue))) {
1049*635a8641SAndroid Build Coastguard Worker return false;
1050*635a8641SAndroid Build Coastguard Worker }
1051*635a8641SAndroid Build Coastguard Worker *p = static_cast<param_type>(value);
1052*635a8641SAndroid Build Coastguard Worker return true;
1053*635a8641SAndroid Build Coastguard Worker }
1054*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)1055*635a8641SAndroid Build Coastguard Worker void ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Log(
1056*635a8641SAndroid Build Coastguard Worker const param_type& p,
1057*635a8641SAndroid Build Coastguard Worker std::string* l) {
1058*635a8641SAndroid Build Coastguard Worker LogParam(static_cast<int>(p), l);
1059*635a8641SAndroid Build Coastguard Worker }
1060*635a8641SAndroid Build Coastguard Worker
1061*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
Write(base::Pickle * m,const param_type & p)1062*635a8641SAndroid Build Coastguard Worker void ParamTraits<PlatformFileForTransit>::Write(base::Pickle* m,
1063*635a8641SAndroid Build Coastguard Worker const param_type& p) {
1064*635a8641SAndroid Build Coastguard Worker m->WriteBool(p.IsValid());
1065*635a8641SAndroid Build Coastguard Worker if (p.IsValid()) {
1066*635a8641SAndroid Build Coastguard Worker HandleWin handle_win(p.GetHandle());
1067*635a8641SAndroid Build Coastguard Worker ParamTraits<HandleWin>::Write(m, handle_win);
1068*635a8641SAndroid Build Coastguard Worker ::CloseHandle(p.GetHandle());
1069*635a8641SAndroid Build Coastguard Worker }
1070*635a8641SAndroid Build Coastguard Worker }
1071*635a8641SAndroid Build Coastguard Worker
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)1072*635a8641SAndroid Build Coastguard Worker bool ParamTraits<PlatformFileForTransit>::Read(const base::Pickle* m,
1073*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
1074*635a8641SAndroid Build Coastguard Worker param_type* r) {
1075*635a8641SAndroid Build Coastguard Worker bool is_valid;
1076*635a8641SAndroid Build Coastguard Worker if (!iter->ReadBool(&is_valid))
1077*635a8641SAndroid Build Coastguard Worker return false;
1078*635a8641SAndroid Build Coastguard Worker if (!is_valid) {
1079*635a8641SAndroid Build Coastguard Worker *r = PlatformFileForTransit();
1080*635a8641SAndroid Build Coastguard Worker return true;
1081*635a8641SAndroid Build Coastguard Worker }
1082*635a8641SAndroid Build Coastguard Worker
1083*635a8641SAndroid Build Coastguard Worker HandleWin handle_win;
1084*635a8641SAndroid Build Coastguard Worker if (!ParamTraits<HandleWin>::Read(m, iter, &handle_win))
1085*635a8641SAndroid Build Coastguard Worker return false;
1086*635a8641SAndroid Build Coastguard Worker *r = PlatformFileForTransit(handle_win.get_handle());
1087*635a8641SAndroid Build Coastguard Worker return true;
1088*635a8641SAndroid Build Coastguard Worker }
1089*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)1090*635a8641SAndroid Build Coastguard Worker void ParamTraits<PlatformFileForTransit>::Log(const param_type& p,
1091*635a8641SAndroid Build Coastguard Worker std::string* l) {
1092*635a8641SAndroid Build Coastguard Worker LogParam(p.GetHandle(), l);
1093*635a8641SAndroid Build Coastguard Worker }
1094*635a8641SAndroid Build Coastguard Worker #endif // defined(OS_WIN)
1095*635a8641SAndroid Build Coastguard Worker
Write(base::Pickle * m,const param_type & p)1096*635a8641SAndroid Build Coastguard Worker void ParamTraits<base::FilePath>::Write(base::Pickle* m, const param_type& p) {
1097*635a8641SAndroid Build Coastguard Worker p.WriteToPickle(m);
1098*635a8641SAndroid Build Coastguard Worker }
1099*635a8641SAndroid Build Coastguard Worker
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)1100*635a8641SAndroid Build Coastguard Worker bool ParamTraits<base::FilePath>::Read(const base::Pickle* m,
1101*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
1102*635a8641SAndroid Build Coastguard Worker param_type* r) {
1103*635a8641SAndroid Build Coastguard Worker return r->ReadFromPickle(iter);
1104*635a8641SAndroid Build Coastguard Worker }
1105*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)1106*635a8641SAndroid Build Coastguard Worker void ParamTraits<base::FilePath>::Log(const param_type& p, std::string* l) {
1107*635a8641SAndroid Build Coastguard Worker ParamTraits<base::FilePath::StringType>::Log(p.value(), l);
1108*635a8641SAndroid Build Coastguard Worker }
1109*635a8641SAndroid Build Coastguard Worker
Write(base::Pickle * m,const param_type & p)1110*635a8641SAndroid Build Coastguard Worker void ParamTraits<base::ListValue>::Write(base::Pickle* m, const param_type& p) {
1111*635a8641SAndroid Build Coastguard Worker WriteValue(m, &p, 0);
1112*635a8641SAndroid Build Coastguard Worker }
1113*635a8641SAndroid Build Coastguard Worker
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)1114*635a8641SAndroid Build Coastguard Worker bool ParamTraits<base::ListValue>::Read(const base::Pickle* m,
1115*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
1116*635a8641SAndroid Build Coastguard Worker param_type* r) {
1117*635a8641SAndroid Build Coastguard Worker int type;
1118*635a8641SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &type) ||
1119*635a8641SAndroid Build Coastguard Worker type != static_cast<int>(base::Value::Type::LIST))
1120*635a8641SAndroid Build Coastguard Worker return false;
1121*635a8641SAndroid Build Coastguard Worker
1122*635a8641SAndroid Build Coastguard Worker return ReadListValue(m, iter, r, 0);
1123*635a8641SAndroid Build Coastguard Worker }
1124*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)1125*635a8641SAndroid Build Coastguard Worker void ParamTraits<base::ListValue>::Log(const param_type& p, std::string* l) {
1126*635a8641SAndroid Build Coastguard Worker std::string json;
1127*635a8641SAndroid Build Coastguard Worker base::JSONWriter::Write(p, &json);
1128*635a8641SAndroid Build Coastguard Worker l->append(json);
1129*635a8641SAndroid Build Coastguard Worker }
1130*635a8641SAndroid Build Coastguard Worker
Write(base::Pickle * m,const param_type & p)1131*635a8641SAndroid Build Coastguard Worker void ParamTraits<base::NullableString16>::Write(base::Pickle* m,
1132*635a8641SAndroid Build Coastguard Worker const param_type& p) {
1133*635a8641SAndroid Build Coastguard Worker WriteParam(m, p.string());
1134*635a8641SAndroid Build Coastguard Worker WriteParam(m, p.is_null());
1135*635a8641SAndroid Build Coastguard Worker }
1136*635a8641SAndroid Build Coastguard Worker
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)1137*635a8641SAndroid Build Coastguard Worker bool ParamTraits<base::NullableString16>::Read(const base::Pickle* m,
1138*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
1139*635a8641SAndroid Build Coastguard Worker param_type* r) {
1140*635a8641SAndroid Build Coastguard Worker base::string16 string;
1141*635a8641SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &string))
1142*635a8641SAndroid Build Coastguard Worker return false;
1143*635a8641SAndroid Build Coastguard Worker bool is_null;
1144*635a8641SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &is_null))
1145*635a8641SAndroid Build Coastguard Worker return false;
1146*635a8641SAndroid Build Coastguard Worker *r = base::NullableString16(string, is_null);
1147*635a8641SAndroid Build Coastguard Worker return true;
1148*635a8641SAndroid Build Coastguard Worker }
1149*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)1150*635a8641SAndroid Build Coastguard Worker void ParamTraits<base::NullableString16>::Log(const param_type& p,
1151*635a8641SAndroid Build Coastguard Worker std::string* l) {
1152*635a8641SAndroid Build Coastguard Worker l->append("(");
1153*635a8641SAndroid Build Coastguard Worker LogParam(p.string(), l);
1154*635a8641SAndroid Build Coastguard Worker l->append(", ");
1155*635a8641SAndroid Build Coastguard Worker LogParam(p.is_null(), l);
1156*635a8641SAndroid Build Coastguard Worker l->append(")");
1157*635a8641SAndroid Build Coastguard Worker }
1158*635a8641SAndroid Build Coastguard Worker
Write(base::Pickle * m,const param_type & p)1159*635a8641SAndroid Build Coastguard Worker void ParamTraits<base::File::Info>::Write(base::Pickle* m,
1160*635a8641SAndroid Build Coastguard Worker const param_type& p) {
1161*635a8641SAndroid Build Coastguard Worker WriteParam(m, p.size);
1162*635a8641SAndroid Build Coastguard Worker WriteParam(m, p.is_directory);
1163*635a8641SAndroid Build Coastguard Worker WriteParam(m, p.last_modified.ToDoubleT());
1164*635a8641SAndroid Build Coastguard Worker WriteParam(m, p.last_accessed.ToDoubleT());
1165*635a8641SAndroid Build Coastguard Worker WriteParam(m, p.creation_time.ToDoubleT());
1166*635a8641SAndroid Build Coastguard Worker }
1167*635a8641SAndroid Build Coastguard Worker
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * p)1168*635a8641SAndroid Build Coastguard Worker bool ParamTraits<base::File::Info>::Read(const base::Pickle* m,
1169*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
1170*635a8641SAndroid Build Coastguard Worker param_type* p) {
1171*635a8641SAndroid Build Coastguard Worker double last_modified, last_accessed, creation_time;
1172*635a8641SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &p->size) ||
1173*635a8641SAndroid Build Coastguard Worker !ReadParam(m, iter, &p->is_directory) ||
1174*635a8641SAndroid Build Coastguard Worker !ReadParam(m, iter, &last_modified) ||
1175*635a8641SAndroid Build Coastguard Worker !ReadParam(m, iter, &last_accessed) ||
1176*635a8641SAndroid Build Coastguard Worker !ReadParam(m, iter, &creation_time))
1177*635a8641SAndroid Build Coastguard Worker return false;
1178*635a8641SAndroid Build Coastguard Worker p->last_modified = base::Time::FromDoubleT(last_modified);
1179*635a8641SAndroid Build Coastguard Worker p->last_accessed = base::Time::FromDoubleT(last_accessed);
1180*635a8641SAndroid Build Coastguard Worker p->creation_time = base::Time::FromDoubleT(creation_time);
1181*635a8641SAndroid Build Coastguard Worker return true;
1182*635a8641SAndroid Build Coastguard Worker }
1183*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)1184*635a8641SAndroid Build Coastguard Worker void ParamTraits<base::File::Info>::Log(const param_type& p,
1185*635a8641SAndroid Build Coastguard Worker std::string* l) {
1186*635a8641SAndroid Build Coastguard Worker l->append("(");
1187*635a8641SAndroid Build Coastguard Worker LogParam(p.size, l);
1188*635a8641SAndroid Build Coastguard Worker l->append(",");
1189*635a8641SAndroid Build Coastguard Worker LogParam(p.is_directory, l);
1190*635a8641SAndroid Build Coastguard Worker l->append(",");
1191*635a8641SAndroid Build Coastguard Worker LogParam(p.last_modified.ToDoubleT(), l);
1192*635a8641SAndroid Build Coastguard Worker l->append(",");
1193*635a8641SAndroid Build Coastguard Worker LogParam(p.last_accessed.ToDoubleT(), l);
1194*635a8641SAndroid Build Coastguard Worker l->append(",");
1195*635a8641SAndroid Build Coastguard Worker LogParam(p.creation_time.ToDoubleT(), l);
1196*635a8641SAndroid Build Coastguard Worker l->append(")");
1197*635a8641SAndroid Build Coastguard Worker }
1198*635a8641SAndroid Build Coastguard Worker
Write(base::Pickle * m,const param_type & p)1199*635a8641SAndroid Build Coastguard Worker void ParamTraits<base::Time>::Write(base::Pickle* m, const param_type& p) {
1200*635a8641SAndroid Build Coastguard Worker ParamTraits<int64_t>::Write(m, p.ToInternalValue());
1201*635a8641SAndroid Build Coastguard Worker }
1202*635a8641SAndroid Build Coastguard Worker
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)1203*635a8641SAndroid Build Coastguard Worker bool ParamTraits<base::Time>::Read(const base::Pickle* m,
1204*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
1205*635a8641SAndroid Build Coastguard Worker param_type* r) {
1206*635a8641SAndroid Build Coastguard Worker int64_t value;
1207*635a8641SAndroid Build Coastguard Worker if (!ParamTraits<int64_t>::Read(m, iter, &value))
1208*635a8641SAndroid Build Coastguard Worker return false;
1209*635a8641SAndroid Build Coastguard Worker *r = base::Time::FromInternalValue(value);
1210*635a8641SAndroid Build Coastguard Worker return true;
1211*635a8641SAndroid Build Coastguard Worker }
1212*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)1213*635a8641SAndroid Build Coastguard Worker void ParamTraits<base::Time>::Log(const param_type& p, std::string* l) {
1214*635a8641SAndroid Build Coastguard Worker ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
1215*635a8641SAndroid Build Coastguard Worker }
1216*635a8641SAndroid Build Coastguard Worker
Write(base::Pickle * m,const param_type & p)1217*635a8641SAndroid Build Coastguard Worker void ParamTraits<base::TimeDelta>::Write(base::Pickle* m, const param_type& p) {
1218*635a8641SAndroid Build Coastguard Worker ParamTraits<int64_t>::Write(m, p.ToInternalValue());
1219*635a8641SAndroid Build Coastguard Worker }
1220*635a8641SAndroid Build Coastguard Worker
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)1221*635a8641SAndroid Build Coastguard Worker bool ParamTraits<base::TimeDelta>::Read(const base::Pickle* m,
1222*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
1223*635a8641SAndroid Build Coastguard Worker param_type* r) {
1224*635a8641SAndroid Build Coastguard Worker int64_t value;
1225*635a8641SAndroid Build Coastguard Worker bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
1226*635a8641SAndroid Build Coastguard Worker if (ret)
1227*635a8641SAndroid Build Coastguard Worker *r = base::TimeDelta::FromInternalValue(value);
1228*635a8641SAndroid Build Coastguard Worker
1229*635a8641SAndroid Build Coastguard Worker return ret;
1230*635a8641SAndroid Build Coastguard Worker }
1231*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)1232*635a8641SAndroid Build Coastguard Worker void ParamTraits<base::TimeDelta>::Log(const param_type& p, std::string* l) {
1233*635a8641SAndroid Build Coastguard Worker ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
1234*635a8641SAndroid Build Coastguard Worker }
1235*635a8641SAndroid Build Coastguard Worker
Write(base::Pickle * m,const param_type & p)1236*635a8641SAndroid Build Coastguard Worker void ParamTraits<base::TimeTicks>::Write(base::Pickle* m, const param_type& p) {
1237*635a8641SAndroid Build Coastguard Worker ParamTraits<int64_t>::Write(m, p.ToInternalValue());
1238*635a8641SAndroid Build Coastguard Worker }
1239*635a8641SAndroid Build Coastguard Worker
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)1240*635a8641SAndroid Build Coastguard Worker bool ParamTraits<base::TimeTicks>::Read(const base::Pickle* m,
1241*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
1242*635a8641SAndroid Build Coastguard Worker param_type* r) {
1243*635a8641SAndroid Build Coastguard Worker int64_t value;
1244*635a8641SAndroid Build Coastguard Worker bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
1245*635a8641SAndroid Build Coastguard Worker if (ret)
1246*635a8641SAndroid Build Coastguard Worker *r = base::TimeTicks::FromInternalValue(value);
1247*635a8641SAndroid Build Coastguard Worker
1248*635a8641SAndroid Build Coastguard Worker return ret;
1249*635a8641SAndroid Build Coastguard Worker }
1250*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)1251*635a8641SAndroid Build Coastguard Worker void ParamTraits<base::TimeTicks>::Log(const param_type& p, std::string* l) {
1252*635a8641SAndroid Build Coastguard Worker ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
1253*635a8641SAndroid Build Coastguard Worker }
1254*635a8641SAndroid Build Coastguard Worker
1255*635a8641SAndroid Build Coastguard Worker // If base::UnguessableToken is no longer 128 bits, the IPC serialization logic
1256*635a8641SAndroid Build Coastguard Worker // below should be updated.
1257*635a8641SAndroid Build Coastguard Worker static_assert(sizeof(base::UnguessableToken) == 2 * sizeof(uint64_t),
1258*635a8641SAndroid Build Coastguard Worker "base::UnguessableToken should be of size 2 * sizeof(uint64_t).");
1259*635a8641SAndroid Build Coastguard Worker
Write(base::Pickle * m,const param_type & p)1260*635a8641SAndroid Build Coastguard Worker void ParamTraits<base::UnguessableToken>::Write(base::Pickle* m,
1261*635a8641SAndroid Build Coastguard Worker const param_type& p) {
1262*635a8641SAndroid Build Coastguard Worker DCHECK(!p.is_empty());
1263*635a8641SAndroid Build Coastguard Worker
1264*635a8641SAndroid Build Coastguard Worker ParamTraits<uint64_t>::Write(m, p.GetHighForSerialization());
1265*635a8641SAndroid Build Coastguard Worker ParamTraits<uint64_t>::Write(m, p.GetLowForSerialization());
1266*635a8641SAndroid Build Coastguard Worker }
1267*635a8641SAndroid Build Coastguard Worker
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)1268*635a8641SAndroid Build Coastguard Worker bool ParamTraits<base::UnguessableToken>::Read(const base::Pickle* m,
1269*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
1270*635a8641SAndroid Build Coastguard Worker param_type* r) {
1271*635a8641SAndroid Build Coastguard Worker uint64_t high, low;
1272*635a8641SAndroid Build Coastguard Worker if (!ParamTraits<uint64_t>::Read(m, iter, &high) ||
1273*635a8641SAndroid Build Coastguard Worker !ParamTraits<uint64_t>::Read(m, iter, &low))
1274*635a8641SAndroid Build Coastguard Worker return false;
1275*635a8641SAndroid Build Coastguard Worker
1276*635a8641SAndroid Build Coastguard Worker // Receiving a zeroed UnguessableToken is a security issue.
1277*635a8641SAndroid Build Coastguard Worker if (high == 0 && low == 0)
1278*635a8641SAndroid Build Coastguard Worker return false;
1279*635a8641SAndroid Build Coastguard Worker
1280*635a8641SAndroid Build Coastguard Worker *r = base::UnguessableToken::Deserialize(high, low);
1281*635a8641SAndroid Build Coastguard Worker return true;
1282*635a8641SAndroid Build Coastguard Worker }
1283*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)1284*635a8641SAndroid Build Coastguard Worker void ParamTraits<base::UnguessableToken>::Log(const param_type& p,
1285*635a8641SAndroid Build Coastguard Worker std::string* l) {
1286*635a8641SAndroid Build Coastguard Worker l->append(p.ToString());
1287*635a8641SAndroid Build Coastguard Worker }
1288*635a8641SAndroid Build Coastguard Worker
Write(base::Pickle * m,const param_type & p)1289*635a8641SAndroid Build Coastguard Worker void ParamTraits<IPC::ChannelHandle>::Write(base::Pickle* m,
1290*635a8641SAndroid Build Coastguard Worker const param_type& p) {
1291*635a8641SAndroid Build Coastguard Worker #if defined(OS_NACL_SFI)
1292*635a8641SAndroid Build Coastguard Worker WriteParam(m, p.socket);
1293*635a8641SAndroid Build Coastguard Worker #else
1294*635a8641SAndroid Build Coastguard Worker WriteParam(m, p.mojo_handle);
1295*635a8641SAndroid Build Coastguard Worker #endif
1296*635a8641SAndroid Build Coastguard Worker }
1297*635a8641SAndroid Build Coastguard Worker
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)1298*635a8641SAndroid Build Coastguard Worker bool ParamTraits<IPC::ChannelHandle>::Read(const base::Pickle* m,
1299*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
1300*635a8641SAndroid Build Coastguard Worker param_type* r) {
1301*635a8641SAndroid Build Coastguard Worker #if defined(OS_NACL_SFI)
1302*635a8641SAndroid Build Coastguard Worker return ReadParam(m, iter, &r->socket);
1303*635a8641SAndroid Build Coastguard Worker #else
1304*635a8641SAndroid Build Coastguard Worker return ReadParam(m, iter, &r->mojo_handle);
1305*635a8641SAndroid Build Coastguard Worker #endif
1306*635a8641SAndroid Build Coastguard Worker }
1307*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)1308*635a8641SAndroid Build Coastguard Worker void ParamTraits<IPC::ChannelHandle>::Log(const param_type& p,
1309*635a8641SAndroid Build Coastguard Worker std::string* l) {
1310*635a8641SAndroid Build Coastguard Worker l->append("ChannelHandle(");
1311*635a8641SAndroid Build Coastguard Worker #if defined(OS_NACL_SFI)
1312*635a8641SAndroid Build Coastguard Worker ParamTraits<base::FileDescriptor>::Log(p.socket, l);
1313*635a8641SAndroid Build Coastguard Worker #else
1314*635a8641SAndroid Build Coastguard Worker LogParam(p.mojo_handle, l);
1315*635a8641SAndroid Build Coastguard Worker #endif
1316*635a8641SAndroid Build Coastguard Worker l->append(")");
1317*635a8641SAndroid Build Coastguard Worker }
1318*635a8641SAndroid Build Coastguard Worker
Write(base::Pickle * m,const param_type & p)1319*635a8641SAndroid Build Coastguard Worker void ParamTraits<LogData>::Write(base::Pickle* m, const param_type& p) {
1320*635a8641SAndroid Build Coastguard Worker WriteParam(m, p.channel);
1321*635a8641SAndroid Build Coastguard Worker WriteParam(m, p.routing_id);
1322*635a8641SAndroid Build Coastguard Worker WriteParam(m, p.type);
1323*635a8641SAndroid Build Coastguard Worker WriteParam(m, p.flags);
1324*635a8641SAndroid Build Coastguard Worker WriteParam(m, p.sent);
1325*635a8641SAndroid Build Coastguard Worker WriteParam(m, p.receive);
1326*635a8641SAndroid Build Coastguard Worker WriteParam(m, p.dispatch);
1327*635a8641SAndroid Build Coastguard Worker WriteParam(m, p.message_name);
1328*635a8641SAndroid Build Coastguard Worker WriteParam(m, p.params);
1329*635a8641SAndroid Build Coastguard Worker }
1330*635a8641SAndroid Build Coastguard Worker
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)1331*635a8641SAndroid Build Coastguard Worker bool ParamTraits<LogData>::Read(const base::Pickle* m,
1332*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
1333*635a8641SAndroid Build Coastguard Worker param_type* r) {
1334*635a8641SAndroid Build Coastguard Worker return
1335*635a8641SAndroid Build Coastguard Worker ReadParam(m, iter, &r->channel) &&
1336*635a8641SAndroid Build Coastguard Worker ReadParam(m, iter, &r->routing_id) &&
1337*635a8641SAndroid Build Coastguard Worker ReadParam(m, iter, &r->type) &&
1338*635a8641SAndroid Build Coastguard Worker ReadParam(m, iter, &r->flags) &&
1339*635a8641SAndroid Build Coastguard Worker ReadParam(m, iter, &r->sent) &&
1340*635a8641SAndroid Build Coastguard Worker ReadParam(m, iter, &r->receive) &&
1341*635a8641SAndroid Build Coastguard Worker ReadParam(m, iter, &r->dispatch) &&
1342*635a8641SAndroid Build Coastguard Worker ReadParam(m, iter, &r->message_name) &&
1343*635a8641SAndroid Build Coastguard Worker ReadParam(m, iter, &r->params);
1344*635a8641SAndroid Build Coastguard Worker }
1345*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)1346*635a8641SAndroid Build Coastguard Worker void ParamTraits<LogData>::Log(const param_type& p, std::string* l) {
1347*635a8641SAndroid Build Coastguard Worker // Doesn't make sense to implement this!
1348*635a8641SAndroid Build Coastguard Worker }
1349*635a8641SAndroid Build Coastguard Worker
Write(base::Pickle * m,const Message & p)1350*635a8641SAndroid Build Coastguard Worker void ParamTraits<Message>::Write(base::Pickle* m, const Message& p) {
1351*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX) || defined(OS_FUCHSIA)
1352*635a8641SAndroid Build Coastguard Worker // We don't serialize the file descriptors in the nested message, so there
1353*635a8641SAndroid Build Coastguard Worker // better not be any.
1354*635a8641SAndroid Build Coastguard Worker DCHECK(!p.HasAttachments());
1355*635a8641SAndroid Build Coastguard Worker #endif
1356*635a8641SAndroid Build Coastguard Worker
1357*635a8641SAndroid Build Coastguard Worker // Don't just write out the message. This is used to send messages between
1358*635a8641SAndroid Build Coastguard Worker // NaCl (Posix environment) and the browser (could be on Windows). The message
1359*635a8641SAndroid Build Coastguard Worker // header formats differ between these systems (so does handle sharing, but
1360*635a8641SAndroid Build Coastguard Worker // we already asserted we don't have any handles). So just write out the
1361*635a8641SAndroid Build Coastguard Worker // parts of the header we use.
1362*635a8641SAndroid Build Coastguard Worker //
1363*635a8641SAndroid Build Coastguard Worker // Be careful also to use only explicitly-sized types. The NaCl environment
1364*635a8641SAndroid Build Coastguard Worker // could be 64-bit and the host browser could be 32-bits. The nested message
1365*635a8641SAndroid Build Coastguard Worker // may or may not be safe to send between 32-bit and 64-bit systems, but we
1366*635a8641SAndroid Build Coastguard Worker // leave that up to the code sending the message to ensure.
1367*635a8641SAndroid Build Coastguard Worker m->WriteUInt32(static_cast<uint32_t>(p.routing_id()));
1368*635a8641SAndroid Build Coastguard Worker m->WriteUInt32(p.type());
1369*635a8641SAndroid Build Coastguard Worker m->WriteUInt32(p.flags());
1370*635a8641SAndroid Build Coastguard Worker m->WriteData(p.payload(), static_cast<uint32_t>(p.payload_size()));
1371*635a8641SAndroid Build Coastguard Worker }
1372*635a8641SAndroid Build Coastguard Worker
Read(const base::Pickle * m,base::PickleIterator * iter,Message * r)1373*635a8641SAndroid Build Coastguard Worker bool ParamTraits<Message>::Read(const base::Pickle* m,
1374*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
1375*635a8641SAndroid Build Coastguard Worker Message* r) {
1376*635a8641SAndroid Build Coastguard Worker uint32_t routing_id, type, flags;
1377*635a8641SAndroid Build Coastguard Worker if (!iter->ReadUInt32(&routing_id) ||
1378*635a8641SAndroid Build Coastguard Worker !iter->ReadUInt32(&type) ||
1379*635a8641SAndroid Build Coastguard Worker !iter->ReadUInt32(&flags))
1380*635a8641SAndroid Build Coastguard Worker return false;
1381*635a8641SAndroid Build Coastguard Worker
1382*635a8641SAndroid Build Coastguard Worker int payload_size;
1383*635a8641SAndroid Build Coastguard Worker const char* payload;
1384*635a8641SAndroid Build Coastguard Worker if (!iter->ReadData(&payload, &payload_size))
1385*635a8641SAndroid Build Coastguard Worker return false;
1386*635a8641SAndroid Build Coastguard Worker
1387*635a8641SAndroid Build Coastguard Worker r->SetHeaderValues(static_cast<int32_t>(routing_id), type, flags);
1388*635a8641SAndroid Build Coastguard Worker r->WriteBytes(payload, payload_size);
1389*635a8641SAndroid Build Coastguard Worker return true;
1390*635a8641SAndroid Build Coastguard Worker }
1391*635a8641SAndroid Build Coastguard Worker
Log(const Message & p,std::string * l)1392*635a8641SAndroid Build Coastguard Worker void ParamTraits<Message>::Log(const Message& p, std::string* l) {
1393*635a8641SAndroid Build Coastguard Worker l->append("<IPC::Message>");
1394*635a8641SAndroid Build Coastguard Worker }
1395*635a8641SAndroid Build Coastguard Worker
1396*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
1397*635a8641SAndroid Build Coastguard Worker // Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
1398*635a8641SAndroid Build Coastguard Worker // bit systems. That's why we use the Windows macros to convert to 32 bits.
Write(base::Pickle * m,const param_type & p)1399*635a8641SAndroid Build Coastguard Worker void ParamTraits<HANDLE>::Write(base::Pickle* m, const param_type& p) {
1400*635a8641SAndroid Build Coastguard Worker m->WriteInt(HandleToLong(p));
1401*635a8641SAndroid Build Coastguard Worker }
1402*635a8641SAndroid Build Coastguard Worker
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)1403*635a8641SAndroid Build Coastguard Worker bool ParamTraits<HANDLE>::Read(const base::Pickle* m,
1404*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
1405*635a8641SAndroid Build Coastguard Worker param_type* r) {
1406*635a8641SAndroid Build Coastguard Worker int32_t temp;
1407*635a8641SAndroid Build Coastguard Worker if (!iter->ReadInt(&temp))
1408*635a8641SAndroid Build Coastguard Worker return false;
1409*635a8641SAndroid Build Coastguard Worker *r = LongToHandle(temp);
1410*635a8641SAndroid Build Coastguard Worker return true;
1411*635a8641SAndroid Build Coastguard Worker }
1412*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)1413*635a8641SAndroid Build Coastguard Worker void ParamTraits<HANDLE>::Log(const param_type& p, std::string* l) {
1414*635a8641SAndroid Build Coastguard Worker l->append(base::StringPrintf("0x%p", p));
1415*635a8641SAndroid Build Coastguard Worker }
1416*635a8641SAndroid Build Coastguard Worker
Write(base::Pickle * m,const param_type & p)1417*635a8641SAndroid Build Coastguard Worker void ParamTraits<MSG>::Write(base::Pickle* m, const param_type& p) {
1418*635a8641SAndroid Build Coastguard Worker m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
1419*635a8641SAndroid Build Coastguard Worker }
1420*635a8641SAndroid Build Coastguard Worker
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)1421*635a8641SAndroid Build Coastguard Worker bool ParamTraits<MSG>::Read(const base::Pickle* m,
1422*635a8641SAndroid Build Coastguard Worker base::PickleIterator* iter,
1423*635a8641SAndroid Build Coastguard Worker param_type* r) {
1424*635a8641SAndroid Build Coastguard Worker const char *data;
1425*635a8641SAndroid Build Coastguard Worker int data_size = 0;
1426*635a8641SAndroid Build Coastguard Worker bool result = iter->ReadData(&data, &data_size);
1427*635a8641SAndroid Build Coastguard Worker if (result && data_size == sizeof(MSG)) {
1428*635a8641SAndroid Build Coastguard Worker memcpy(r, data, sizeof(MSG));
1429*635a8641SAndroid Build Coastguard Worker } else {
1430*635a8641SAndroid Build Coastguard Worker result = false;
1431*635a8641SAndroid Build Coastguard Worker NOTREACHED();
1432*635a8641SAndroid Build Coastguard Worker }
1433*635a8641SAndroid Build Coastguard Worker
1434*635a8641SAndroid Build Coastguard Worker return result;
1435*635a8641SAndroid Build Coastguard Worker }
1436*635a8641SAndroid Build Coastguard Worker
Log(const param_type & p,std::string * l)1437*635a8641SAndroid Build Coastguard Worker void ParamTraits<MSG>::Log(const param_type& p, std::string* l) {
1438*635a8641SAndroid Build Coastguard Worker l->append("<MSG>");
1439*635a8641SAndroid Build Coastguard Worker }
1440*635a8641SAndroid Build Coastguard Worker
1441*635a8641SAndroid Build Coastguard Worker #endif // OS_WIN
1442*635a8641SAndroid Build Coastguard Worker
1443*635a8641SAndroid Build Coastguard Worker } // namespace IPC
1444