MIDI Metrics: Send MIDI Metrics to statsd
This CL sends MIDI Metrics to statsd.
Bug: 248607712
Test: adb shell dumpsys media.metrics
Test: statsd_testdrive
Change-Id: I5818a6e47fd098d05cc6f08a34cd61fd13eccb01
diff --git a/media/libmediametrics/include/MediaMetricsConstants.h b/media/libmediametrics/include/MediaMetricsConstants.h
index 27f987d..ba3df59 100644
--- a/media/libmediametrics/include/MediaMetricsConstants.h
+++ b/media/libmediametrics/include/MediaMetricsConstants.h
@@ -72,6 +72,7 @@
// Keys are strings used for MediaMetrics Item Keys
#define AMEDIAMETRICS_KEY_AUDIO_FLINGER AMEDIAMETRICS_KEY_PREFIX_AUDIO "flinger"
+#define AMEDIAMETRICS_KEY_AUDIO_MIDI AMEDIAMETRICS_KEY_PREFIX_AUDIO "midi"
#define AMEDIAMETRICS_KEY_AUDIO_POLICY AMEDIAMETRICS_KEY_PREFIX_AUDIO "policy"
// Error keys
@@ -124,9 +125,13 @@
#define AMEDIAMETRICS_PROP_CHANNELMASK "channelMask" // int32
#define AMEDIAMETRICS_PROP_CHANNELMASKS "channelMasks" // string with channelMask values
// separated by |.
+#define AMEDIAMETRICS_PROP_CLOSEDCOUNT "closedCount" // int32 (MIDI)
#define AMEDIAMETRICS_PROP_CONTENTTYPE "contentType" // string attributes (AudioTrack)
#define AMEDIAMETRICS_PROP_CUMULATIVETIMENS "cumulativeTimeNs" // int64_t playback/record time
// since start
+#define AMEDIAMETRICS_PROP_DEVICEDISCONNECTED "deviceDisconnected" // string true/false (MIDI)
+#define AMEDIAMETRICS_PROP_DEVICEID "deviceId" // int32 device id (MIDI)
+
// DEVICE values are averaged since starting on device
#define AMEDIAMETRICS_PROP_DEVICELATENCYMS "deviceLatencyMs" // double - avg latency time
#define AMEDIAMETRICS_PROP_DEVICESTARTUPMS "deviceStartupMs" // double - avg startup time
@@ -150,12 +155,15 @@
#define AMEDIAMETRICS_PROP_FLAGS "flags"
#define AMEDIAMETRICS_PROP_FRAMECOUNT "frameCount" // int32
+#define AMEDIAMETRICS_PROP_HARDWARETYPE "hardwareType" // int32 (MIDI)
#define AMEDIAMETRICS_PROP_HASHEADTRACKER "hasHeadTracker" // string true/false
#define AMEDIAMETRICS_PROP_HEADTRACKERENABLED "headTrackerEnabled" // string true/false
#define AMEDIAMETRICS_PROP_HEADTRACKINGMODES "headTrackingModes" // string |, like modes.
#define AMEDIAMETRICS_PROP_INPUTDEVICES "inputDevices" // string value
+#define AMEDIAMETRICS_PROP_INPUTPORTCOUNT "inputPortCount" // int32 (MIDI)
#define AMEDIAMETRICS_PROP_INTERNALTRACKID "internalTrackId" // int32
#define AMEDIAMETRICS_PROP_INTERVALCOUNT "intervalCount" // int32
+#define AMEDIAMETRICS_PROP_ISSHARED "isShared" // string true/false (MIDI)
#define AMEDIAMETRICS_PROP_LATENCYMS "latencyMs" // double value
#define AMEDIAMETRICS_PROP_LEVELS "levels" // string | with levels
#define AMEDIAMETRICS_PROP_LOGSESSIONID "logSessionId" // hex string, "" none
@@ -165,7 +173,9 @@
#define AMEDIAMETRICS_PROP_MODES "modes" // string | with modes
#define AMEDIAMETRICS_PROP_NAME "name" // string value
#define AMEDIAMETRICS_PROP_ORIGINALFLAGS "originalFlags" // int32
+#define AMEDIAMETRICS_PROP_OPENEDCOUNT "openedCount" // int32 (MIDI)
#define AMEDIAMETRICS_PROP_OUTPUTDEVICES "outputDevices" // string value
+#define AMEDIAMETRICS_PROP_OUTPUTPORTCOUNT "outputPortCount" // int32 (MIDI)
#define AMEDIAMETRICS_PROP_PERFORMANCEMODE "performanceMode" // string value, "none", lowLatency"
#define AMEDIAMETRICS_PROP_PLAYBACK_PITCH "playback.pitch" // double value (AudioTrack)
#define AMEDIAMETRICS_PROP_PLAYBACK_SPEED "playback.speed" // double value (AudioTrack)
@@ -194,6 +204,13 @@
// Treated as "debug" information.
#define AMEDIAMETRICS_PROP_STREAMTYPE "streamType" // string (AudioTrack)
+#define AMEDIAMETRICS_PROP_SUPPORTSMIDIUMP "supportsMidiUmp" // string true/false (MIDI).
+ // Universal MIDI Packets is a new
+ // format to transport packets.
+ // Raw byte streams are used if this
+ // is false.
+#define AMEDIAMETRICS_PROP_TOTALINPUTBYTES "totalInputBytes" // int32 (MIDI)
+#define AMEDIAMETRICS_PROP_TOTALOUTPUTBYTES "totalOutputBytes" // int32 (MIDI)
#define AMEDIAMETRICS_PROP_THREADID "threadId" // int32 value io handle
#define AMEDIAMETRICS_PROP_THROTTLEMS "throttleMs" // double
#define AMEDIAMETRICS_PROP_TRACKID "trackId" // int32 port id of track/record
@@ -202,6 +219,7 @@
#define AMEDIAMETRICS_PROP_UNDERRUN "underrun" // int32
#define AMEDIAMETRICS_PROP_UNDERRUNFRAMES "underrunFrames" // int64_t from Thread
#define AMEDIAMETRICS_PROP_USAGE "usage" // string attributes (ATrack)
+#define AMEDIAMETRICS_PROP_USINGALSA "usingAlsa" // string true/false (MIDI)
#define AMEDIAMETRICS_PROP_VOICEVOLUME "voiceVolume" // double (audio.flinger)
#define AMEDIAMETRICS_PROP_VOLUME_LEFT "volume.left" // double (AudioTrack)
#define AMEDIAMETRICS_PROP_VOLUME_RIGHT "volume.right" // double (AudioTrack)
@@ -226,6 +244,7 @@
#define AMEDIAMETRICS_PROP_EVENT_VALUE_CREATE "create"
#define AMEDIAMETRICS_PROP_EVENT_VALUE_CREATEAUDIOPATCH "createAudioPatch"
#define AMEDIAMETRICS_PROP_EVENT_VALUE_CTOR "ctor"
+#define AMEDIAMETRICS_PROP_EVENT_VALUE_DEVICECLOSED "deviceClosed" // MIDI
#define AMEDIAMETRICS_PROP_EVENT_VALUE_DISCONNECT "disconnect"
#define AMEDIAMETRICS_PROP_EVENT_VALUE_DTOR "dtor"
#define AMEDIAMETRICS_PROP_EVENT_VALUE_ENDAAUDIOSTREAM "endAAudioStream" // AAudioStream
diff --git a/services/mediametrics/AudioAnalytics.cpp b/services/mediametrics/AudioAnalytics.cpp
index 119bb6c..7af6c41 100644
--- a/services/mediametrics/AudioAnalytics.cpp
+++ b/services/mediametrics/AudioAnalytics.cpp
@@ -269,6 +269,24 @@
"enabled",
};
+static constexpr const char * const MidiDeviceCloseFields[] {
+ "mediametrics_midi_device_close_reported",
+ "uid",
+ "midi_device_id",
+ "input_port_count",
+ "output_port_count",
+ "device_type",
+ "is_shared",
+ "supports_ump",
+ "using_alsa",
+ "duration_ns",
+ "opened_count",
+ "closed_count",
+ "device_disconnected",
+ "total_input_bytes",
+ "total_output_bytes",
+};
+
/**
* printFields is a helper method that prints the fields and corresponding values
* in a human readable style.
@@ -497,6 +515,15 @@
[this](const std::shared_ptr<const android::mediametrics::Item> &item){
mSpatializer.onEvent(item);
}));
+
+ // Handle MIDI
+ mActions.addAction(
+ AMEDIAMETRICS_KEY_AUDIO_MIDI "." AMEDIAMETRICS_PROP_EVENT,
+ std::string(AMEDIAMETRICS_PROP_EVENT_VALUE_DEVICECLOSED),
+ std::make_shared<AnalyticsActions::Function>(
+ [this](const std::shared_ptr<const android::mediametrics::Item> &item) {
+ mMidiLogging.onEvent(item);
+ }));
}
AudioAnalytics::~AudioAnalytics()
@@ -1710,6 +1737,127 @@
return { s, n };
}
+void AudioAnalytics::MidiLogging::onEvent(
+ const std::shared_ptr<const android::mediametrics::Item> &item) const {
+ const std::string& key = item->getKey();
+
+ const auto uid = item->getUid();
+
+ int32_t deviceId = -1;
+ mAudioAnalytics.mAnalyticsState->timeMachine().get(
+ key, AMEDIAMETRICS_PROP_DEVICEID, &deviceId);
+
+ int32_t inputPortCount = -1;
+ mAudioAnalytics.mAnalyticsState->timeMachine().get(
+ key, AMEDIAMETRICS_PROP_INPUTPORTCOUNT, &inputPortCount);
+
+ int32_t outputPortCount = -1;
+ mAudioAnalytics.mAnalyticsState->timeMachine().get(
+ key, AMEDIAMETRICS_PROP_OUTPUTPORTCOUNT, &outputPortCount);
+
+ int32_t hardwareType = -1;
+ mAudioAnalytics.mAnalyticsState->timeMachine().get(
+ key, AMEDIAMETRICS_PROP_HARDWARETYPE, &hardwareType);
+
+ std::string isSharedString;
+ mAudioAnalytics.mAnalyticsState->timeMachine().get(
+ key, AMEDIAMETRICS_PROP_ISSHARED, &isSharedString);
+ const bool isShared = (isSharedString == "true");
+
+ std::string supportsMidiUmpString;
+ mAudioAnalytics.mAnalyticsState->timeMachine().get(
+ key, AMEDIAMETRICS_PROP_SUPPORTSMIDIUMP, &supportsMidiUmpString);
+ const bool supportsMidiUmp = (supportsMidiUmpString == "true");
+
+ std::string usingAlsaString;
+ mAudioAnalytics.mAnalyticsState->timeMachine().get(
+ key, AMEDIAMETRICS_PROP_USINGALSA, &usingAlsaString);
+ const bool usingAlsa = (usingAlsaString == "true");
+
+ int64_t durationNs = -1;
+ mAudioAnalytics.mAnalyticsState->timeMachine().get(
+ key, AMEDIAMETRICS_PROP_DURATIONNS, &durationNs);
+
+ int32_t openedCount = -1;
+ mAudioAnalytics.mAnalyticsState->timeMachine().get(
+ key, AMEDIAMETRICS_PROP_OPENEDCOUNT, &openedCount);
+
+ int32_t closedCount = -1;
+ mAudioAnalytics.mAnalyticsState->timeMachine().get(
+ key, AMEDIAMETRICS_PROP_CLOSEDCOUNT, &closedCount);
+
+ std::string deviceDisconnectedString;
+ mAudioAnalytics.mAnalyticsState->timeMachine().get(
+ key, AMEDIAMETRICS_PROP_DEVICEDISCONNECTED, &deviceDisconnectedString);
+ const bool deviceDisconnected = (deviceDisconnectedString == "true");
+
+ int32_t totalInputBytes = -1;
+ mAudioAnalytics.mAnalyticsState->timeMachine().get(
+ key, AMEDIAMETRICS_PROP_TOTALINPUTBYTES, &totalInputBytes);
+
+ int32_t totalOutputBytes = -1;
+ mAudioAnalytics.mAnalyticsState->timeMachine().get(
+ key, AMEDIAMETRICS_PROP_TOTALOUTPUTBYTES, &totalOutputBytes);
+
+ LOG(LOG_LEVEL) << "key:" << key
+ << " uid:" << uid
+ << " id:" << deviceId
+ << " input_port_count:" << inputPortCount
+ << " output_port_count:" << outputPortCount
+ << " device_type:" << hardwareType
+ << " is_shared:" << isSharedString
+ << " supports_ump:" << supportsMidiUmpString
+ << " using_alsa:" << usingAlsaString
+ << " duration_opened_ms:" << durationNs
+ << " opened_count:" << openedCount
+ << " closed_count:" << closedCount
+ << " device_disconnected:" << deviceDisconnectedString
+ << " total_input_bytes:" << totalInputBytes
+ << " total_output_bytes:" << totalOutputBytes;
+
+ if (mAudioAnalytics.mDeliverStatistics) {
+ const auto result = sendToStatsd(
+ CONDITION(stats::media_metrics::MEDIAMETRICS_MIDI_DEVICE_CLOSE_REPORTED)
+ , uid
+ , deviceId
+ , inputPortCount
+ , outputPortCount
+ , hardwareType
+ , isShared
+ , supportsMidiUmp
+ , usingAlsa
+ , durationNs
+ , openedCount
+ , closedCount
+ , deviceDisconnected
+ , totalInputBytes
+ , totalOutputBytes);
+ std::stringstream ss;
+ ss << "result:" << result;
+ const auto fieldsStr = printFields(MidiDeviceCloseFields,
+ CONDITION(stats::media_metrics::MEDIAMETRICS_MIDI_DEVICE_CLOSE_REPORTED)
+ , uid
+ , deviceId
+ , inputPortCount
+ , outputPortCount
+ , hardwareType
+ , isShared
+ , supportsMidiUmp
+ , usingAlsa
+ , durationNs
+ , openedCount
+ , closedCount
+ , deviceDisconnected
+ , totalInputBytes
+ , totalOutputBytes);
+ ss << " " << fieldsStr;
+ std::string str = ss.str();
+ ALOGV("%s: statsd %s", __func__, str.c_str());
+ mAudioAnalytics.mStatsdLog->log(
+ stats::media_metrics::MEDIAMETRICS_MIDI_DEVICE_CLOSE_REPORTED, str);
+ }
+}
+
// This method currently suppresses the name.
std::string AudioAnalytics::getDeviceNamesFromOutputDevices(std::string_view devices) const {
std::string deviceNames;
diff --git a/services/mediametrics/include/mediametricsservice/AudioAnalytics.h b/services/mediametrics/include/mediametricsservice/AudioAnalytics.h
index 82e928e..f0a4ac8 100644
--- a/services/mediametrics/include/mediametricsservice/AudioAnalytics.h
+++ b/services/mediametrics/include/mediametricsservice/AudioAnalytics.h
@@ -363,6 +363,20 @@
SimpleLog mSimpleLog GUARDED_BY(mLock) {64};
} mSpatializer{*this};
+ // MidiLogging collects info whenever a MIDI device is closed.
+ class MidiLogging {
+ public:
+ explicit MidiLogging(AudioAnalytics &audioAnalytics)
+ : mAudioAnalytics(audioAnalytics) {}
+
+ void onEvent(
+ const std::shared_ptr<const android::mediametrics::Item> &item) const;
+
+ private:
+
+ AudioAnalytics &mAudioAnalytics;
+ } mMidiLogging{*this};
+
AudioPowerUsage mAudioPowerUsage;
};