Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/mozilla/TelemetryComms.h
Line
Count
Source (jump to first uncovered line)
1
/* -*-  Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
2
/* This Source Code Form is subject to the terms of the Mozilla Public
3
 * License, v. 2.0. If a copy of the MPL was not distributed with this
4
 */
5
6
#ifndef Telemetry_Comms_h__
7
#define Telemetry_Comms_h__
8
9
#include "ipc/IPCMessageUtils.h"
10
#include "nsITelemetry.h"
11
#include "nsVariant.h"
12
#include "mozilla/TimeStamp.h"
13
#include "mozilla/TelemetryProcessEnums.h"
14
15
namespace mozilla {
16
namespace Telemetry {
17
18
// Histogram accumulation types.
19
enum HistogramID : uint32_t;
20
21
struct HistogramAccumulation
22
{
23
  mozilla::Telemetry::HistogramID mId;
24
  uint32_t mSample;
25
};
26
27
struct KeyedHistogramAccumulation
28
{
29
  mozilla::Telemetry::HistogramID mId;
30
  uint32_t mSample;
31
  nsCString mKey;
32
};
33
34
// Scalar accumulation types.
35
enum class ScalarID : uint32_t;
36
37
enum class ScalarActionType : uint32_t {
38
  eSet = 0,
39
  eAdd = 1,
40
  eSetMaximum = 2
41
};
42
43
typedef mozilla::Variant<uint32_t, bool, nsString> ScalarVariant;
44
45
struct ScalarAction
46
{
47
  uint32_t mId;
48
  bool mDynamic;
49
  ScalarActionType mActionType;
50
  // We need to wrap mData in a Maybe otherwise the IPC system
51
  // is unable to instantiate a ScalarAction.
52
  Maybe<ScalarVariant> mData;
53
  // The process type this scalar should be recorded for.
54
  // The IPC system will determine the process this action was coming from later.
55
  mozilla::Telemetry::ProcessID mProcessType;
56
};
57
58
struct KeyedScalarAction
59
{
60
  uint32_t mId;
61
  bool mDynamic;
62
  ScalarActionType mActionType;
63
  nsCString mKey;
64
  // We need to wrap mData in a Maybe otherwise the IPC system
65
  // is unable to instantiate a ScalarAction.
66
  Maybe<ScalarVariant> mData;
67
  // The process type this scalar should be recorded for.
68
  // The IPC system will determine the process this action was coming from later.
69
  mozilla::Telemetry::ProcessID mProcessType;
70
};
71
72
// Dynamic scalars support.
73
struct DynamicScalarDefinition
74
{
75
  uint32_t type;
76
  uint32_t dataset;
77
  bool expired;
78
  bool keyed;
79
  nsCString name;
80
81
  bool operator ==(const DynamicScalarDefinition& rhs) const
82
0
  {
83
0
    return type == rhs.type &&
84
0
           dataset == rhs.dataset &&
85
0
           expired == rhs.expired &&
86
0
           keyed == rhs.keyed &&
87
0
           name.Equals(rhs.name);
88
0
  }
89
};
90
91
struct EventExtraEntry {
92
  nsCString key;
93
  nsCString value;
94
};
95
96
struct ChildEventData {
97
  mozilla::TimeStamp timestamp;
98
  nsCString category;
99
  nsCString method;
100
  nsCString object;
101
  mozilla::Maybe<nsCString> value;
102
  nsTArray<EventExtraEntry> extra;
103
};
104
105
struct DiscardedData {
106
  uint32_t mDiscardedHistogramAccumulations;
107
  uint32_t mDiscardedKeyedHistogramAccumulations;
108
  uint32_t mDiscardedScalarActions;
109
  uint32_t mDiscardedKeyedScalarActions;
110
  uint32_t mDiscardedChildEvents;
111
};
112
113
} // namespace Telemetry
114
} // namespace mozilla
115
116
namespace IPC {
117
118
template<>
119
struct
120
ParamTraits<mozilla::Telemetry::HistogramAccumulation>
121
{
122
  typedef mozilla::Telemetry::HistogramAccumulation paramType;
123
124
  static void Write(Message* aMsg, const paramType& aParam)
125
0
  {
126
0
    aMsg->WriteUInt32(aParam.mId);
127
0
    WriteParam(aMsg, aParam.mSample);
128
0
  }
129
130
  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
131
0
  {
132
0
    if (!aMsg->ReadUInt32(aIter, reinterpret_cast<uint32_t*>(&(aResult->mId))) ||
133
0
        !ReadParam(aMsg, aIter, &(aResult->mSample))) {
134
0
      return false;
135
0
    }
136
0
137
0
    return true;
138
0
  }
139
};
140
141
template<>
142
struct
143
ParamTraits<mozilla::Telemetry::KeyedHistogramAccumulation>
144
{
145
  typedef mozilla::Telemetry::KeyedHistogramAccumulation paramType;
146
147
  static void Write(Message* aMsg, const paramType& aParam)
148
0
  {
149
0
    aMsg->WriteUInt32(aParam.mId);
150
0
    WriteParam(aMsg, aParam.mSample);
151
0
    WriteParam(aMsg, aParam.mKey);
152
0
  }
153
154
  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
155
0
  {
156
0
    if (!aMsg->ReadUInt32(aIter, reinterpret_cast<uint32_t*>(&(aResult->mId))) ||
157
0
        !ReadParam(aMsg, aIter, &(aResult->mSample)) ||
158
0
        !ReadParam(aMsg, aIter, &(aResult->mKey))) {
159
0
      return false;
160
0
    }
161
0
162
0
    return true;
163
0
  }
164
};
165
166
/**
167
 * IPC scalar data message serialization and de-serialization.
168
 */
169
template<>
170
struct
171
ParamTraits<mozilla::Telemetry::ScalarAction>
172
{
173
  typedef mozilla::Telemetry::ScalarAction paramType;
174
175
  static void Write(Message* aMsg, const paramType& aParam)
176
0
  {
177
0
    // Write the message type
178
0
    aMsg->WriteUInt32(aParam.mId);
179
0
    WriteParam(aMsg, aParam.mDynamic);
180
0
    WriteParam(aMsg, static_cast<uint32_t>(aParam.mActionType));
181
0
182
0
    if (aParam.mData.isNothing()) {
183
0
      MOZ_CRASH("There is no data in the ScalarAction.");
184
0
      return;
185
0
    }
186
0
187
0
    if (aParam.mData->is<uint32_t>()) {
188
0
      // That's a nsITelemetry::SCALAR_TYPE_COUNT.
189
0
      WriteParam(aMsg, static_cast<uint32_t>(nsITelemetry::SCALAR_TYPE_COUNT));
190
0
      WriteParam(aMsg, aParam.mData->as<uint32_t>());
191
0
    } else if (aParam.mData->is<nsString>()) {
192
0
      // That's a nsITelemetry::SCALAR_TYPE_STRING.
193
0
      WriteParam(aMsg, static_cast<uint32_t>(nsITelemetry::SCALAR_TYPE_STRING));
194
0
      WriteParam(aMsg, aParam.mData->as<nsString>());
195
0
    } else if (aParam.mData->is<bool>()) {
196
0
      // That's a nsITelemetry::SCALAR_TYPE_BOOLEAN.
197
0
      WriteParam(aMsg, static_cast<uint32_t>(nsITelemetry::SCALAR_TYPE_BOOLEAN));
198
0
      WriteParam(aMsg, aParam.mData->as<bool>());
199
0
    } else {
200
0
      MOZ_CRASH("Unknown scalar type.");
201
0
    }
202
0
  }
203
204
  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
205
0
  {
206
0
    // Read the scalar ID and the scalar type.
207
0
    uint32_t scalarType = 0;
208
0
    if (!aMsg->ReadUInt32(aIter, reinterpret_cast<uint32_t*>(&(aResult->mId))) ||
209
0
        !ReadParam(aMsg, aIter, reinterpret_cast<bool*>(&(aResult->mDynamic))) ||
210
0
        !ReadParam(aMsg, aIter, reinterpret_cast<uint32_t*>(&(aResult->mActionType))) ||
211
0
        !ReadParam(aMsg, aIter, &scalarType)) {
212
0
      return false;
213
0
    }
214
0
215
0
    // De-serialize the data based on the scalar type.
216
0
    switch (scalarType)
217
0
    {
218
0
      case nsITelemetry::SCALAR_TYPE_COUNT:
219
0
        {
220
0
          uint32_t data = 0;
221
0
          // De-serialize the data.
222
0
          if (!ReadParam(aMsg, aIter, &data)) {
223
0
            return false;
224
0
          }
225
0
          aResult->mData = mozilla::Some(mozilla::AsVariant(data));
226
0
          break;
227
0
        }
228
0
      case nsITelemetry::SCALAR_TYPE_STRING:
229
0
        {
230
0
          nsString data;
231
0
          // De-serialize the data.
232
0
          if (!ReadParam(aMsg, aIter, &data)) {
233
0
            return false;
234
0
          }
235
0
          aResult->mData = mozilla::Some(mozilla::AsVariant(data));
236
0
          break;
237
0
        }
238
0
      case nsITelemetry::SCALAR_TYPE_BOOLEAN:
239
0
        {
240
0
          bool data = false;
241
0
          // De-serialize the data.
242
0
          if (!ReadParam(aMsg, aIter, &data)) {
243
0
            return false;
244
0
          }
245
0
          aResult->mData = mozilla::Some(mozilla::AsVariant(data));
246
0
          break;
247
0
        }
248
0
      default:
249
0
        MOZ_ASSERT(false, "Unknown scalar type.");
250
0
        return false;
251
0
    }
252
0
253
0
    return true;
254
0
  }
255
};
256
257
/**
258
 * IPC keyed scalar data message serialization and de-serialization.
259
 */
260
template<>
261
struct
262
ParamTraits<mozilla::Telemetry::KeyedScalarAction>
263
{
264
  typedef mozilla::Telemetry::KeyedScalarAction paramType;
265
266
  static void Write(Message* aMsg, const paramType& aParam)
267
0
  {
268
0
    // Write the message type
269
0
    aMsg->WriteUInt32(static_cast<uint32_t>(aParam.mId));
270
0
    WriteParam(aMsg, aParam.mDynamic);
271
0
    WriteParam(aMsg, static_cast<uint32_t>(aParam.mActionType));
272
0
    WriteParam(aMsg, aParam.mKey);
273
0
274
0
    if (aParam.mData.isNothing()) {
275
0
      MOZ_CRASH("There is no data in the KeyedScalarAction.");
276
0
      return;
277
0
    }
278
0
279
0
    if (aParam.mData->is<uint32_t>()) {
280
0
      // That's a nsITelemetry::SCALAR_TYPE_COUNT.
281
0
      WriteParam(aMsg, static_cast<uint32_t>(nsITelemetry::SCALAR_TYPE_COUNT));
282
0
      WriteParam(aMsg, aParam.mData->as<uint32_t>());
283
0
    } else if (aParam.mData->is<nsString>()) {
284
0
      // That's a nsITelemetry::SCALAR_TYPE_STRING.
285
0
      // Keyed string scalars are not supported.
286
0
      MOZ_ASSERT(false, "Keyed String Scalar unable to be write from child process. Not supported.");
287
0
    } else if (aParam.mData->is<bool>()) {
288
0
      // That's a nsITelemetry::SCALAR_TYPE_BOOLEAN.
289
0
      WriteParam(aMsg, static_cast<uint32_t>(nsITelemetry::SCALAR_TYPE_BOOLEAN));
290
0
      WriteParam(aMsg, aParam.mData->as<bool>());
291
0
    } else {
292
0
      MOZ_CRASH("Unknown keyed scalar type.");
293
0
    }
294
0
  }
295
296
  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
297
0
  {
298
0
    // Read the scalar ID and the scalar type.
299
0
    uint32_t scalarType = 0;
300
0
    if (!aMsg->ReadUInt32(aIter, reinterpret_cast<uint32_t*>(&(aResult->mId))) ||
301
0
        !ReadParam(aMsg, aIter, reinterpret_cast<bool*>(&(aResult->mDynamic))) ||
302
0
        !ReadParam(aMsg, aIter, reinterpret_cast<uint32_t*>(&(aResult->mActionType))) ||
303
0
        !ReadParam(aMsg, aIter, &(aResult->mKey)) ||
304
0
        !ReadParam(aMsg, aIter, &scalarType)) {
305
0
      return false;
306
0
    }
307
0
308
0
    // De-serialize the data based on the scalar type.
309
0
    switch (scalarType)
310
0
    {
311
0
      case nsITelemetry::SCALAR_TYPE_COUNT:
312
0
        {
313
0
          uint32_t data = 0;
314
0
          // De-serialize the data.
315
0
          if (!ReadParam(aMsg, aIter, &data)) {
316
0
            return false;
317
0
          }
318
0
          aResult->mData = mozilla::Some(mozilla::AsVariant(data));
319
0
          break;
320
0
        }
321
0
      case nsITelemetry::SCALAR_TYPE_STRING:
322
0
        {
323
0
          // Keyed string scalars are not supported.
324
0
          MOZ_ASSERT(false, "Keyed String Scalar unable to be read from child process. Not supported.");
325
0
          return false;
326
0
        }
327
0
      case nsITelemetry::SCALAR_TYPE_BOOLEAN:
328
0
        {
329
0
          bool data = false;
330
0
          // De-serialize the data.
331
0
          if (!ReadParam(aMsg, aIter, &data)) {
332
0
            return false;
333
0
          }
334
0
          aResult->mData = mozilla::Some(mozilla::AsVariant(data));
335
0
          break;
336
0
        }
337
0
      default:
338
0
        MOZ_ASSERT(false, "Unknown keyed scalar type.");
339
0
        return false;
340
0
    }
341
0
342
0
    return true;
343
0
  }
344
};
345
346
template<>
347
struct
348
ParamTraits<mozilla::Telemetry::DynamicScalarDefinition>
349
{
350
  typedef mozilla::Telemetry::DynamicScalarDefinition paramType;
351
352
  static void Write(Message* aMsg, const paramType& aParam)
353
0
  {
354
0
    nsCString name;
355
0
    WriteParam(aMsg, aParam.type);
356
0
    WriteParam(aMsg, aParam.dataset);
357
0
    WriteParam(aMsg, aParam.expired);
358
0
    WriteParam(aMsg, aParam.keyed);
359
0
    WriteParam(aMsg, aParam.name);
360
0
  }
361
362
  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
363
0
  {
364
0
    if (!ReadParam(aMsg, aIter, reinterpret_cast<uint32_t*>(&(aResult->type))) ||
365
0
        !ReadParam(aMsg, aIter, reinterpret_cast<uint32_t*>(&(aResult->dataset))) ||
366
0
        !ReadParam(aMsg, aIter, reinterpret_cast<bool*>(&(aResult->expired))) ||
367
0
        !ReadParam(aMsg, aIter, reinterpret_cast<bool*>(&(aResult->keyed))) ||
368
0
        !ReadParam(aMsg, aIter, &(aResult->name))) {
369
0
      return false;
370
0
    }
371
0
    return true;
372
0
  }
373
};
374
375
template<>
376
struct
377
ParamTraits<mozilla::Telemetry::ChildEventData>
378
{
379
  typedef mozilla::Telemetry::ChildEventData paramType;
380
381
  static void Write(Message* aMsg, const paramType& aParam)
382
0
  {
383
0
    WriteParam(aMsg, aParam.timestamp);
384
0
    WriteParam(aMsg, aParam.category);
385
0
    WriteParam(aMsg, aParam.method);
386
0
    WriteParam(aMsg, aParam.object);
387
0
    WriteParam(aMsg, aParam.value);
388
0
    WriteParam(aMsg, aParam.extra);
389
0
  }
390
391
  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
392
0
  {
393
0
    if (!ReadParam(aMsg, aIter, &(aResult->timestamp)) ||
394
0
        !ReadParam(aMsg, aIter, &(aResult->category)) ||
395
0
        !ReadParam(aMsg, aIter, &(aResult->method)) ||
396
0
        !ReadParam(aMsg, aIter, &(aResult->object)) ||
397
0
        !ReadParam(aMsg, aIter, &(aResult->value)) ||
398
0
        !ReadParam(aMsg, aIter, &(aResult->extra))) {
399
0
      return false;
400
0
    }
401
0
402
0
    return true;
403
0
  }
404
};
405
406
template<>
407
struct
408
ParamTraits<mozilla::Telemetry::EventExtraEntry>
409
{
410
  typedef mozilla::Telemetry::EventExtraEntry paramType;
411
412
  static void Write(Message* aMsg, const paramType& aParam)
413
0
  {
414
0
    WriteParam(aMsg, aParam.key);
415
0
    WriteParam(aMsg, aParam.value);
416
0
  }
417
418
  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
419
0
  {
420
0
    if (!ReadParam(aMsg, aIter, &(aResult->key)) ||
421
0
        !ReadParam(aMsg, aIter, &(aResult->value))) {
422
0
      return false;
423
0
    }
424
0
425
0
    return true;
426
0
  }
427
};
428
429
template<>
430
struct
431
ParamTraits<mozilla::Telemetry::DiscardedData>
432
  : public PlainOldDataSerializer<mozilla::Telemetry::DiscardedData>
433
{ };
434
435
} // namespace IPC
436
437
#endif // Telemetry_Comms_h__