Files
tubestation/toolkit/components/telemetry/ipc/TelemetryComms.h
Alessio Placitelli e24412e896 Bug 1393801 - Enable dynamic scalar registration. f=gfritzsche,r=billm,chutten
MozReview-Commit-ID: JlRk7hLV5QD
2017-08-29 13:05:40 +02:00

431 lines
12 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
*/
#ifndef Telemetry_Comms_h__
#define Telemetry_Comms_h__
#include "ipc/IPCMessageUtils.h"
#include "nsITelemetry.h"
#include "nsVariant.h"
#include "mozilla/TimeStamp.h"
namespace mozilla {
namespace Telemetry {
// Histogram accumulation types.
enum HistogramID : uint32_t;
struct HistogramAccumulation
{
mozilla::Telemetry::HistogramID mId;
uint32_t mSample;
};
struct KeyedHistogramAccumulation
{
mozilla::Telemetry::HistogramID mId;
uint32_t mSample;
nsCString mKey;
};
// Scalar accumulation types.
enum class ScalarID : uint32_t;
enum class ScalarActionType : uint32_t {
eSet = 0,
eAdd = 1,
eSetMaximum = 2
};
typedef mozilla::Variant<uint32_t, bool, nsString> ScalarVariant;
struct ScalarAction
{
uint32_t mId;
bool mDynamic;
ScalarActionType mActionType;
// We need to wrap mData in a Maybe otherwise the IPC system
// is unable to instantiate a ScalarAction.
Maybe<ScalarVariant> mData;
};
struct KeyedScalarAction
{
uint32_t mId;
bool mDynamic;
ScalarActionType mActionType;
nsCString mKey;
// We need to wrap mData in a Maybe otherwise the IPC system
// is unable to instantiate a ScalarAction.
Maybe<ScalarVariant> mData;
};
// Dynamic scalars support.
struct DynamicScalarDefinition
{
uint32_t type;
uint32_t dataset;
bool expired;
bool keyed;
nsCString name;
bool operator ==(const DynamicScalarDefinition& rhs) const
{
return type == rhs.type &&
dataset == rhs.dataset &&
expired == rhs.expired &&
keyed == rhs.keyed &&
name.Equals(rhs.name);
}
};
struct EventExtraEntry {
nsCString key;
nsCString value;
};
struct ChildEventData {
mozilla::TimeStamp timestamp;
nsCString category;
nsCString method;
nsCString object;
mozilla::Maybe<nsCString> value;
nsTArray<EventExtraEntry> extra;
};
struct DiscardedData {
uint32_t mDiscardedHistogramAccumulations;
uint32_t mDiscardedKeyedHistogramAccumulations;
uint32_t mDiscardedScalarActions;
uint32_t mDiscardedKeyedScalarActions;
uint32_t mDiscardedChildEvents;
};
} // namespace Telemetry
} // namespace mozilla
namespace IPC {
template<>
struct
ParamTraits<mozilla::Telemetry::HistogramAccumulation>
{
typedef mozilla::Telemetry::HistogramAccumulation paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
aMsg->WriteUInt32(aParam.mId);
WriteParam(aMsg, aParam.mSample);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
if (!aMsg->ReadUInt32(aIter, reinterpret_cast<uint32_t*>(&(aResult->mId))) ||
!ReadParam(aMsg, aIter, &(aResult->mSample))) {
return false;
}
return true;
}
};
template<>
struct
ParamTraits<mozilla::Telemetry::KeyedHistogramAccumulation>
{
typedef mozilla::Telemetry::KeyedHistogramAccumulation paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
aMsg->WriteUInt32(aParam.mId);
WriteParam(aMsg, aParam.mSample);
WriteParam(aMsg, aParam.mKey);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
if (!aMsg->ReadUInt32(aIter, reinterpret_cast<uint32_t*>(&(aResult->mId))) ||
!ReadParam(aMsg, aIter, &(aResult->mSample)) ||
!ReadParam(aMsg, aIter, &(aResult->mKey))) {
return false;
}
return true;
}
};
/**
* IPC scalar data message serialization and de-serialization.
*/
template<>
struct
ParamTraits<mozilla::Telemetry::ScalarAction>
{
typedef mozilla::Telemetry::ScalarAction paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
// Write the message type
aMsg->WriteUInt32(aParam.mId);
WriteParam(aMsg, aParam.mDynamic);
WriteParam(aMsg, static_cast<uint32_t>(aParam.mActionType));
if (aParam.mData.isNothing()) {
MOZ_CRASH("There is no data in the ScalarAction.");
return;
}
if (aParam.mData->is<uint32_t>()) {
// That's a nsITelemetry::SCALAR_TYPE_COUNT.
WriteParam(aMsg, static_cast<uint32_t>(nsITelemetry::SCALAR_TYPE_COUNT));
WriteParam(aMsg, aParam.mData->as<uint32_t>());
} else if (aParam.mData->is<nsString>()) {
// That's a nsITelemetry::SCALAR_TYPE_STRING.
WriteParam(aMsg, static_cast<uint32_t>(nsITelemetry::SCALAR_TYPE_STRING));
WriteParam(aMsg, aParam.mData->as<nsString>());
} else if (aParam.mData->is<bool>()) {
// That's a nsITelemetry::SCALAR_TYPE_BOOLEAN.
WriteParam(aMsg, static_cast<uint32_t>(nsITelemetry::SCALAR_TYPE_BOOLEAN));
WriteParam(aMsg, aParam.mData->as<bool>());
} else {
MOZ_CRASH("Unknown scalar type.");
}
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
// Read the scalar ID and the scalar type.
uint32_t scalarType = 0;
if (!aMsg->ReadUInt32(aIter, reinterpret_cast<uint32_t*>(&(aResult->mId))) ||
!ReadParam(aMsg, aIter, reinterpret_cast<bool*>(&(aResult->mDynamic))) ||
!ReadParam(aMsg, aIter, reinterpret_cast<uint32_t*>(&(aResult->mActionType))) ||
!ReadParam(aMsg, aIter, &scalarType)) {
return false;
}
// De-serialize the data based on the scalar type.
switch (scalarType)
{
case nsITelemetry::SCALAR_TYPE_COUNT:
{
uint32_t data = 0;
// De-serialize the data.
if (!ReadParam(aMsg, aIter, &data)) {
return false;
}
aResult->mData = mozilla::Some(mozilla::AsVariant(data));
break;
}
case nsITelemetry::SCALAR_TYPE_STRING:
{
nsString data;
// De-serialize the data.
if (!ReadParam(aMsg, aIter, &data)) {
return false;
}
aResult->mData = mozilla::Some(mozilla::AsVariant(data));
break;
}
case nsITelemetry::SCALAR_TYPE_BOOLEAN:
{
bool data = false;
// De-serialize the data.
if (!ReadParam(aMsg, aIter, &data)) {
return false;
}
aResult->mData = mozilla::Some(mozilla::AsVariant(data));
break;
}
default:
MOZ_ASSERT(false, "Unknown scalar type.");
return false;
}
return true;
}
};
/**
* IPC keyed scalar data message serialization and de-serialization.
*/
template<>
struct
ParamTraits<mozilla::Telemetry::KeyedScalarAction>
{
typedef mozilla::Telemetry::KeyedScalarAction paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
// Write the message type
aMsg->WriteUInt32(static_cast<uint32_t>(aParam.mId));
WriteParam(aMsg, aParam.mDynamic);
WriteParam(aMsg, static_cast<uint32_t>(aParam.mActionType));
WriteParam(aMsg, aParam.mKey);
if (aParam.mData.isNothing()) {
MOZ_CRASH("There is no data in the KeyedScalarAction.");
return;
}
if (aParam.mData->is<uint32_t>()) {
// That's a nsITelemetry::SCALAR_TYPE_COUNT.
WriteParam(aMsg, static_cast<uint32_t>(nsITelemetry::SCALAR_TYPE_COUNT));
WriteParam(aMsg, aParam.mData->as<uint32_t>());
} else if (aParam.mData->is<nsString>()) {
// That's a nsITelemetry::SCALAR_TYPE_STRING.
// Keyed string scalars are not supported.
MOZ_ASSERT(false, "Keyed String Scalar unable to be write from child process. Not supported.");
} else if (aParam.mData->is<bool>()) {
// That's a nsITelemetry::SCALAR_TYPE_BOOLEAN.
WriteParam(aMsg, static_cast<uint32_t>(nsITelemetry::SCALAR_TYPE_BOOLEAN));
WriteParam(aMsg, aParam.mData->as<bool>());
} else {
MOZ_CRASH("Unknown keyed scalar type.");
}
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
// Read the scalar ID and the scalar type.
uint32_t scalarType = 0;
if (!aMsg->ReadUInt32(aIter, reinterpret_cast<uint32_t*>(&(aResult->mId))) ||
!ReadParam(aMsg, aIter, reinterpret_cast<bool*>(&(aResult->mDynamic))) ||
!ReadParam(aMsg, aIter, reinterpret_cast<uint32_t*>(&(aResult->mActionType))) ||
!ReadParam(aMsg, aIter, &(aResult->mKey)) ||
!ReadParam(aMsg, aIter, &scalarType)) {
return false;
}
// De-serialize the data based on the scalar type.
switch (scalarType)
{
case nsITelemetry::SCALAR_TYPE_COUNT:
{
uint32_t data = 0;
// De-serialize the data.
if (!ReadParam(aMsg, aIter, &data)) {
return false;
}
aResult->mData = mozilla::Some(mozilla::AsVariant(data));
break;
}
case nsITelemetry::SCALAR_TYPE_STRING:
{
// Keyed string scalars are not supported.
MOZ_ASSERT(false, "Keyed String Scalar unable to be read from child process. Not supported.");
return false;
}
case nsITelemetry::SCALAR_TYPE_BOOLEAN:
{
bool data = false;
// De-serialize the data.
if (!ReadParam(aMsg, aIter, &data)) {
return false;
}
aResult->mData = mozilla::Some(mozilla::AsVariant(data));
break;
}
default:
MOZ_ASSERT(false, "Unknown keyed scalar type.");
return false;
}
return true;
}
};
template<>
struct
ParamTraits<mozilla::Telemetry::DynamicScalarDefinition>
{
typedef mozilla::Telemetry::DynamicScalarDefinition paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
nsCString name;
WriteParam(aMsg, aParam.type);
WriteParam(aMsg, aParam.dataset);
WriteParam(aMsg, aParam.expired);
WriteParam(aMsg, aParam.keyed);
WriteParam(aMsg, aParam.name);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
if (!ReadParam(aMsg, aIter, reinterpret_cast<uint32_t*>(&(aResult->type))) ||
!ReadParam(aMsg, aIter, reinterpret_cast<uint32_t*>(&(aResult->dataset))) ||
!ReadParam(aMsg, aIter, reinterpret_cast<bool*>(&(aResult->expired))) ||
!ReadParam(aMsg, aIter, reinterpret_cast<bool*>(&(aResult->keyed))) ||
!ReadParam(aMsg, aIter, &(aResult->name))) {
return false;
}
return true;
}
};
template<>
struct
ParamTraits<mozilla::Telemetry::ChildEventData>
{
typedef mozilla::Telemetry::ChildEventData paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, aParam.timestamp);
WriteParam(aMsg, aParam.category);
WriteParam(aMsg, aParam.method);
WriteParam(aMsg, aParam.object);
WriteParam(aMsg, aParam.value);
WriteParam(aMsg, aParam.extra);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
if (!ReadParam(aMsg, aIter, &(aResult->timestamp)) ||
!ReadParam(aMsg, aIter, &(aResult->category)) ||
!ReadParam(aMsg, aIter, &(aResult->method)) ||
!ReadParam(aMsg, aIter, &(aResult->object)) ||
!ReadParam(aMsg, aIter, &(aResult->value)) ||
!ReadParam(aMsg, aIter, &(aResult->extra))) {
return false;
}
return true;
}
};
template<>
struct
ParamTraits<mozilla::Telemetry::EventExtraEntry>
{
typedef mozilla::Telemetry::EventExtraEntry paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, aParam.key);
WriteParam(aMsg, aParam.value);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
if (!ReadParam(aMsg, aIter, &(aResult->key)) ||
!ReadParam(aMsg, aIter, &(aResult->value))) {
return false;
}
return true;
}
};
template<>
struct
ParamTraits<mozilla::Telemetry::DiscardedData>
: public PlainOldDataSerializer<mozilla::Telemetry::DiscardedData>
{ };
} // namespace IPC
#endif // Telemetry_Comms_h__