MediaMetrics: Prepare audio device usage protos for statsd

MediaMetricsAudioRecordDeviceUsageReported
MediaMetricsAudioThreadDeviceUsageReported
MediaMetricsAudioTrackDeviceUsageReported
MediaMetricsAudioDeviceConnectionReported

Add track traits to identify static AudioTracks.
Fix AudioTrack/AudioRecord flag communication.
Move debug logging to verbose (delivered protos show in dumpsys).
Unknown strings which fail validation become empty.
Test statsd type validation.

Test: atest mediametrics_tests
Test: adb shell dumpsys media.metrics (after BT connection)
Test: statsd_testdrive (294-297)
Bug: 149850236
Change-Id: I53c5d18a346af54941007b9938a8ab10e34b7038
diff --git a/services/mediametrics/StringUtils.h b/services/mediametrics/StringUtils.h
index d878720..7a8bbee 100644
--- a/services/mediametrics/StringUtils.h
+++ b/services/mediametrics/StringUtils.h
@@ -22,6 +22,30 @@
 namespace android::mediametrics::stringutils {
 
 /**
+ * fieldPrint is a helper method that logs to a stringstream a sequence of
+ * field names (in a fixed size array) together with a variable number of arg parameters.
+ *
+ * stringstream << field[0] << ":" << arg0 << " ";
+ * stringstream << field[1] << ":" << arg1 << " ";
+ * ...
+ * stringstream << field[N-1] << ":" << arg{N-1} << " ";
+ *
+ * The number of fields must exactly match the (variable) arguments.
+ *
+ * Example:
+ *
+ * const char * const fields[] = { "integer" };
+ * std::stringstream ss;
+ * fieldPrint(ss, fields, int(10));
+ */
+template <size_t N, typename... Targs>
+void fieldPrint(std::stringstream& ss, const char * const (& fields)[N], Targs... args) {
+    static_assert(N == sizeof...(args));          // guarantee #fields == #args
+    auto fptr = fields;                           // get a pointer to the base of fields array
+    ((ss << *fptr++ << ":" << args << " "), ...); // (fold expression), send to stringstream.
+}
+
+/**
  * Return string tokens from iterator, separated by spaces and reserved chars.
  */
 std::string tokenizer(std::string::const_iterator& it,