AudioTrack: Refine metrics error collection.
Ensure variables set before error collection
as they may happen early in set.
Test: atest AudioTrackTest
Test: adb shell dumpsys media.metrics
Bug: 199763036
Change-Id: Idc8ecbf8307d5bace098baf1a45735e786305576
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index 407b294..24fd625 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -199,6 +199,7 @@
#define MM_PREFIX "android.media.audiotrack." // avoid cut-n-paste errors.
+ // Do not change this without changing the MediaMetricsService side.
// Java API 28 entries, do not change.
mMetricsItem->setCString(MM_PREFIX "streamtype", toString(track->streamType()).c_str());
mMetricsItem->setCString(MM_PREFIX "type",
@@ -214,6 +215,7 @@
mMetricsItem->setInt32(MM_PREFIX "frameCount", (int32_t)track->mFrameCount);
mMetricsItem->setCString(MM_PREFIX "attributes", toString(track->mAttributes).c_str());
mMetricsItem->setCString(MM_PREFIX "logSessionId", track->mLogSessionId.c_str());
+ mMetricsItem->setInt32(MM_PREFIX "underrunFrames", (int32_t)track->getUnderrunFrames());
}
// hand the user a snapshot of the metrics.
@@ -550,8 +552,18 @@
sessionId, transferType, attributionSource.uid, attributionSource.pid);
mThreadCanCallJava = threadCanCallJava;
+
+ // These variables are pulled in an error report, so we initialize them early.
mSelectedDeviceId = selectedDeviceId;
mSessionId = sessionId;
+ mChannelMask = channelMask;
+ mFormat = format;
+ mOrigFlags = mFlags = flags;
+ mReqFrameCount = mFrameCount = frameCount;
+ mSampleRate = sampleRate;
+ mOriginalSampleRate = sampleRate;
+ mAttributes = pAttributes != nullptr ? *pAttributes : AUDIO_ATTRIBUTES_INITIALIZER;
+ mPlaybackRate = AUDIO_PLAYBACK_RATE_DEFAULT;
switch (transferType) {
case TRANSFER_DEFAULT:
@@ -626,7 +638,6 @@
} else {
// stream type shouldn't be looked at, this track has audio attributes
- memcpy(&mAttributes, pAttributes, sizeof(audio_attributes_t));
ALOGV("%s(): Building AudioTrack with attributes:"
" usage=%d content=%d flags=0x%x tags=[%s]",
__func__,
@@ -648,14 +659,12 @@
status = BAD_VALUE;
goto error;
}
- mFormat = format;
if (!audio_is_output_channel(channelMask)) {
errorMessage = StringPrintf("%s: Invalid channel mask %#x", __func__, channelMask);
status = BAD_VALUE;
goto error;
}
- mChannelMask = channelMask;
channelCount = audio_channel_count_from_out_mask(channelMask);
mChannelCount = channelCount;
@@ -697,9 +706,6 @@
status = BAD_VALUE;
goto error;
}
- mSampleRate = sampleRate;
- mOriginalSampleRate = sampleRate;
- mPlaybackRate = AUDIO_PLAYBACK_RATE_DEFAULT;
// 1.0 <= mMaxRequiredSpeed <= AUDIO_TIMESTRETCH_SPEED_MAX
mMaxRequiredSpeed = min(max(maxRequiredSpeed, 1.0f), AUDIO_TIMESTRETCH_SPEED_MAX);
@@ -719,7 +725,6 @@
mVolume[AUDIO_INTERLEAVE_RIGHT] = 1.0f;
mSendLevel = 0.0f;
// mFrameCount is initialized in createTrack_l
- mReqFrameCount = frameCount;
if (notificationFrames >= 0) {
mNotificationFramesReq = notificationFrames;
mNotificationsPerBufferReq = 0;
@@ -760,7 +765,6 @@
mClientAttributionSource.pid = VALUE_OR_FATAL(legacy2aidl_uid_t_int32_t(callingPid));
}
mAuxEffectId = 0;
- mOrigFlags = mFlags = flags;
mCallback = callback;
if (_callback != nullptr) {
@@ -2155,7 +2159,8 @@
if (status == NO_ERROR) return;
// We report error on the native side because some callers do not come
// from Java.
- mediametrics::LogItem(std::string(AMEDIAMETRICS_KEY_PREFIX_AUDIO_TRACK) + "error")
+ // Ensure these variables are initialized in set().
+ mediametrics::LogItem(AMEDIAMETRICS_KEY_AUDIO_TRACK_ERROR)
.set(AMEDIAMETRICS_PROP_EVENT, event)
.set(AMEDIAMETRICS_PROP_ERROR, mediametrics::statusToErrorString(status))
.set(AMEDIAMETRICS_PROP_ERRORMESSAGE, message)
@@ -2166,8 +2171,10 @@
.set(AMEDIAMETRICS_PROP_SELECTEDDEVICEID, (int32_t)mSelectedDeviceId)
.set(AMEDIAMETRICS_PROP_ENCODING, toString(mFormat).c_str())
.set(AMEDIAMETRICS_PROP_CHANNELMASK, (int32_t)mChannelMask)
- .set(AMEDIAMETRICS_PROP_FRAMECOUNT, (int32_t)mReqFrameCount) // requested frame count
// the following are NOT immutable
+ // frame count is initially the requested frame count, but may be adjusted
+ // by AudioFlinger after creation.
+ .set(AMEDIAMETRICS_PROP_FRAMECOUNT, (int32_t)mFrameCount)
.set(AMEDIAMETRICS_PROP_SAMPLERATE, (int32_t)mSampleRate)
.set(AMEDIAMETRICS_PROP_PLAYBACK_SPEED, (double)mPlaybackRate.mSpeed)
.set(AMEDIAMETRICS_PROP_PLAYBACK_PITCH, (double)mPlaybackRate.mPitch)