// Copyright 2017 Google LLC. All Rights Reserved. This file and proprietary // source code may only be used and distributed under the Widevine License // Agreement. // // This file contains the declarations for the Metric class and related // types. #ifndef WVCDM_METRICS_VALUE_METRIC_H_ #define WVCDM_METRICS_VALUE_METRIC_H_ #include #include #include #include "wv_metrics.pb.h" namespace wvcdm { namespace metrics { namespace internal { // Helper function for setting a value in the proto. template void SetValue(drm_metrics::ValueMetric* value_proto, const T& value); } // namespace internal // 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: // ValueMetric cdm_version().Record("a.b.c.d"); // std::unique_ptr mymetric( // cdm_version.ToProto()); // // Example Error Usage: // // ValueMetric cdm_version().SetError(error_code); // std::unique_ptr mymetric( // cdm_version.ToProto()); // template class ValueMetric { public: // Record the value of the metric. void Record(const T& value) { std::unique_lock lock(mutex_); value_ = value; state_ = kHasValue; } // Set the error code if an error was encountered. void SetError(int error_code) { std::unique_lock lock(mutex_); error_code_ = error_code; state_ = kHasError; } bool HasValue() const { std::unique_lock lock(mutex_); return state_ == kHasValue; } const T& GetValue() const { std::unique_lock lock(mutex_); return value_; } bool HasError() const { std::unique_lock lock(mutex_); return state_ == kHasError; } int GetError() const { std::unique_lock lock(mutex_); return error_code_; } // Clears the indicators that the metric or error was set. void Clear() { std::unique_lock lock(mutex_); state_ = kNone; } // 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() const { std::unique_lock lock(mutex_); switch (state_) { case kHasValue: { drm_metrics::ValueMetric* value_proto = new drm_metrics::ValueMetric; internal::SetValue(value_proto, value_); return value_proto; } case kHasError: { drm_metrics::ValueMetric* value_proto = new drm_metrics::ValueMetric; value_proto->set_error_code(error_code_); return value_proto; } case kNone: default: return nullptr; } } private: enum ValueState { kNone, kHasValue, kHasError }; T value_ = T(); int error_code_ = 0; ValueState state_ = kNone; // This locks the internal state of the value metric to ensure safety // across multiple threads preventing the caller from worrying about // locking. mutable std::mutex mutex_; }; } // namespace metrics } // namespace wvcdm #endif // WVCDM_METRICS_VALUE_METRIC_H_