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

@@ -8,69 +8,44 @@
#include <stdint.h>
#include <string>
#include "metric_serialization.h"
#include "metrics.pb.h"
namespace wvcdm {
namespace metrics {
// Private namespace for some helper implementation functions.
// Internal namespace for helper methods.
namespace impl {
// These helper functions map the templated ValueMetric class
// Serialize call to the MetricSerializer explicit calls.
template<typename T>
void Serialize(MetricSerializer* serializer,
const std::string& metric_name, const T& t);
// Helper function for setting a value in the proto.
template <typename T>
void SetValue(drm_metrics::ValueMetric *value_proto, const T &value);
inline void SerializeError(MetricSerializer* serializer,
const std::string& metric_name,
const int& error_code) {
serializer->SetInt32(metric_name + "/error", error_code);
}
} // namespace impl
} // namespace impl
// The Metric class supports storing a single value which can be overwritten.
// the Metric class also supports the MetricSerializer interface through
// which the value can be serialized. If the value was never given a value
// or an error code, then the metric will not serialize anything.
// The ValueMetric class supports storing a single, overwritable value or an
// error code. This class can be serialized to a drm_metrics::ValueMetric proto.
// If an error or value was not provided, this metric will serialize to nullptr.
//
// Example Usage:
// Metric<string> cdm_version("drm/cdm/version")
// .Record("a.b.c.d");
//
// MyMetricSerializerImpl serialzer;
// cdm_version.Serialize(&serializer);
// Metric<string> cdm_version().Record("a.b.c.d");
// std::unique_ptr<drm_metrics::ValueMetric> mymetric(
// cdm_version.ToProto());
//
// Example Error Usage:
//
// Metric<string> cdm_version("drm/cdm/version")
// .SetError(error_code);
// Metric<string> cdm_version().SetError(error_code);
// std::unique_ptr<drm_metrics::ValueMetric> mymetric(
// cdm_version.ToProto());
//
// Note that serialization is the same. But the ValueMetric will serialize
// the error code to <metric_name>/error instead of just <metric_name>.
template<typename T>
class ValueMetric : public MetricSerializable {
template <typename T>
class ValueMetric {
public:
// Constructs a metric with the given metric name.
explicit ValueMetric(const std::string& metric_name)
: metric_name_(metric_name), error_code_(0),
has_error_(false), has_value_(false) {}
// Serialize the metric name and value using the given serializer.
// Caller owns |serializer| which cannot be null.
virtual void Serialize(MetricSerializer* serializer) {
if (has_value_) {
impl::Serialize(serializer, metric_name_, value_);
} else if (has_error_) {
impl::SerializeError(serializer, metric_name_, error_code_);
} else {
// Do nothing if there is no value and no error.
}
}
explicit ValueMetric()
: error_code_(0), has_error_(false), has_value_(false) {}
// Record the value of the metric.
void Record(const T& value) {
void Record(const T &value) {
value_ = value;
has_value_ = true;
has_error_ = false;
@@ -83,8 +58,11 @@ class ValueMetric : public MetricSerializable {
has_error_ = true;
}
// Get the current value of the metric.
const T& GetValue() { return value_; }
bool HasValue() const { return has_value_; }
const T &GetValue() const { return value_; }
bool HasError() const { return has_error_; }
int GetError() const { return error_code_; }
// Clears the indicators that the metric or error was set.
void Clear() {
@@ -92,8 +70,23 @@ class ValueMetric : public MetricSerializable {
has_error_ = false;
}
// Returns a new ValueMetric proto containing the metric value or the
// error code. If neither the error or value are set, it returns nullptr.
drm_metrics::ValueMetric *ToProto() {
if (has_error_) {
drm_metrics::ValueMetric *value_proto = new drm_metrics::ValueMetric;
value_proto->set_error_code(error_code_);
return value_proto;
} else if (has_value_) {
drm_metrics::ValueMetric *value_proto = new drm_metrics::ValueMetric;
impl::SetValue(value_proto, value_);
return value_proto;
}
return NULL;
}
private:
std::string metric_name_;
T value_;
int error_code_;
bool has_error_;