Fixes widevine metrics proto serialization

Changes to a much more efficient and more reusable protobuf format for
metrics.

Test: Widevine tests, Google Play and MediaDrm CTS test.
Bug: 73724218

Change-Id: I3299051d7a16bcd7758c8f272415ca40e10c1313
This commit is contained in:
Adam Stone
2018-02-20 19:12:02 -08:00
parent efc008c5a1
commit b19f0d106f
25 changed files with 1587 additions and 1867 deletions

View File

@@ -5,13 +5,8 @@
#ifndef WVCDM_METRICS_FIELD_TUPLES_H_
#define WVCDM_METRICS_FIELD_TUPLES_H_
#include <cstdarg>
#include <memory>
#include <ostream>
#include <sstream>
#include <stdint.h>
#include <string>
#include <vector>
namespace wvcdm {
namespace metrics {
@@ -24,103 +19,11 @@ namespace util {
// templated classes with "variable" type arguments.
struct Unused {
// Required for compilation. Should never be used.
inline friend std::ostream& operator<< (std::ostream& out, const Unused&)
{ return out; }
inline friend std::ostream& operator<<(std::ostream& out, const Unused&) {
return out;
}
};
// This utility method formats the collection of field name/value pairs.
// The format of the string is:
//
// [{field:value[&field:value]*}]
//
// If there are no pairs, returns a blank string.
template<typename F1, typename F2, typename F3, typename F4>
std::string MakeFieldNameString(const std::vector<std::string>& field_names,
const F1 field1, const F2 field2,
const F3 field3, const F4 field4) {
std::stringstream field_name_and_values;
std::vector<std::string>::const_iterator field_name_iterator =
field_names.begin();
if (field_name_iterator == field_names.end()) {
return field_name_and_values.str();
}
// There is at least one name/value pair. Prepend open brace.
field_name_and_values << "{";
field_name_and_values << *field_name_iterator << ':' << field1;
if (++field_name_iterator == field_names.end()) {
field_name_and_values << "}";
return field_name_and_values.str();
}
field_name_and_values << '&' << *field_name_iterator << ':' << field2;
if (++field_name_iterator == field_names.end()) {
field_name_and_values << "}";
return field_name_and_values.str();
}
field_name_and_values << '&' << *field_name_iterator << ':' << field3;
if (++field_name_iterator == field_names.end()) {
field_name_and_values << "}";
return field_name_and_values.str();
}
field_name_and_values << '&' << *field_name_iterator << ':' << field4;
field_name_and_values << "}";
return field_name_and_values.str();
}
// This specialization of the helper method is a shortcut for class
// instances with no fields.
template<>
inline std::string MakeFieldNameString<Unused, Unused, Unused, Unused>(
const std::vector<std::string>& /* field_names */,
const Unused /* unused1 */, const Unused /* unused2 */,
const Unused /* unused3 */, const Unused /* unused4 */) {
return "";
}
// This helper function appends the field names to a vector of strings.
inline void AppendFieldNames(std::vector<std::string>* field_name_vector,
int field_count, ...) {
va_list field_names;
va_start(field_names, field_count);
for (int x = 0; x < field_count; x++) {
field_name_vector->push_back(va_arg(field_names, const char*));
}
va_end(field_names);
}
// These helper methods and FirstUnusedType assure that there is no mismatch
// between the specified types for metrics type parameters and the constructors
// and methods used for the specializations.
template <bool>
struct CompileAssert {};
#define COMPILE_ASSERT(expr, msg) \
typedef util::CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1] \
__attribute__((unused))
template <typename T> struct is_unused { static const bool value = false; };
template <> struct is_unused<Unused> { static const bool value = true; };
template <typename F1, typename F2, typename F3, typename F4>
class FirstUnusedType {
static const bool a = is_unused<F1>::value;
static const bool b = is_unused<F2>::value;
static const bool c = is_unused<F3>::value;
static const bool d = is_unused<F4>::value;
// Check that all types after the first Unused are also Unused.
COMPILE_ASSERT(a <= b, Invalid_Unused_At_Position_2);
COMPILE_ASSERT(b <= c, Invalid_Unused_At_Position_3);
COMPILE_ASSERT(c <= d, Invalid_Unused_At_Position_4);
public:
static const int value = 5 - (a + b + c + d);
};
// Asserts that no Unused types exist before N; after N, are all Unused types.
#define ASSERT_METRIC_UNUSED_START_FROM(N) \
COMPILE_ASSERT((\
util::FirstUnusedType<F1, F2, F3, F4>::value) == N, \
Unused_Start_From_##N)
} // namespace util
} // namespace metrics
} // namespace wvcdm