diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp index bedde4364d..94253a4cde 100644 --- a/media/libaudioclient/Android.bp +++ b/media/libaudioclient/Android.bp @@ -47,6 +47,9 @@ cc_library_shared { "libdl", "libaudioutils", "libaudiomanager", + "libmedia_helper", + "libmediametrics", + "libstagefright_foundation", ], export_shared_lib_headers: ["libbinder"], diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp index 6d829a0741..76709828d1 100644 --- a/media/libaudioclient/AudioTrack.cpp +++ b/media/libaudioclient/AudioTrack.cpp @@ -31,6 +31,8 @@ #include #include #include +#include +#include #define WAIT_PERIOD_MS 10 #define WAIT_STREAM_END_TIMEOUT_SEC 120 @@ -157,6 +159,65 @@ status_t AudioTrack::getMinFrameCount( // --------------------------------------------------------------------------- +static std::string audioContentTypeString(audio_content_type_t value) { + std::string contentType; + if (AudioContentTypeConverter::toString(value, contentType)) { + return contentType; + } + char rawbuffer[16]; // room for "%d" + snprintf(rawbuffer, sizeof(rawbuffer), "%d", value); + return rawbuffer; +} + +static std::string audioUsageString(audio_usage_t value) { + std::string usage; + if (UsageTypeConverter::toString(value, usage)) { + return usage; + } + char rawbuffer[16]; // room for "%d" + snprintf(rawbuffer, sizeof(rawbuffer), "%d", value); + return rawbuffer; +} + +void AudioTrack::MediaMetrics::gather(const AudioTrack *track) +{ + + // key for media statistics is defined in the header + // attrs for media statistics + static constexpr char kAudioTrackStreamType[] = "android.media.audiotrack.streamtype"; + static constexpr char kAudioTrackContentType[] = "android.media.audiotrack.type"; + static constexpr char kAudioTrackUsage[] = "android.media.audiotrack.usage"; + static constexpr char kAudioTrackSampleRate[] = "android.media.audiotrack.samplerate"; + static constexpr char kAudioTrackChannelMask[] = "android.media.audiotrack.channelmask"; + static constexpr char kAudioTrackUnderrunFrames[] = "android.media.audiotrack.underrunframes"; + static constexpr char kAudioTrackStartupGlitch[] = "android.media.audiotrack.glitch.startup"; + + // constructor guarantees mAnalyticsItem is valid + + // must gather underrun info before cleaning mProxy information. + const int32_t underrunFrames = track->getUnderrunFrames(); + if (underrunFrames != 0) { + mAnalyticsItem->setInt32(kAudioTrackUnderrunFrames, underrunFrames); + } + + if (track->mTimestampStartupGlitchReported) { + mAnalyticsItem->setInt32(kAudioTrackStartupGlitch, 1); + } + + if (track->mStreamType != -1) { + // deprecated, but this will tell us who still uses it. + mAnalyticsItem->setInt32(kAudioTrackStreamType, track->mStreamType); + } + // XXX: consider including from mAttributes: source type + mAnalyticsItem->setCString(kAudioTrackContentType, + audioContentTypeString(track->mAttributes.content_type).c_str()); + mAnalyticsItem->setCString(kAudioTrackUsage, + audioUsageString(track->mAttributes.usage).c_str()); + mAnalyticsItem->setInt32(kAudioTrackSampleRate, track->mSampleRate); + mAnalyticsItem->setInt64(kAudioTrackChannelMask, track->mChannelMask); +} + + AudioTrack::AudioTrack() : mStatus(NO_INIT), mState(STATE_STOPPED), @@ -236,6 +297,9 @@ AudioTrack::AudioTrack( AudioTrack::~AudioTrack() { + // pull together the numbers, before we clean up our structures + mMediaMetrics.gather(this); + if (mStatus == NO_ERROR) { // Make sure that callback function exits in the case where // it is looping on buffer full condition in obtainBuffer(). diff --git a/media/libaudioclient/include/media/AudioTrack.h b/media/libaudioclient/include/media/AudioTrack.h index 9fbd04b6a5..c146db95e1 100644 --- a/media/libaudioclient/include/media/AudioTrack.h +++ b/media/libaudioclient/include/media/AudioTrack.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -1182,6 +1183,25 @@ private: pid_t mClientPid; wp mDeviceCallback; + +private: + class MediaMetrics { + public: + MediaMetrics() : mAnalyticsItem(new MediaAnalyticsItem("audiotrack")) { + } + ~MediaMetrics() { + // mAnalyticsItem alloc failure will be flagged in the constructor + // don't log empty records + if (mAnalyticsItem->count() > 0) { + mAnalyticsItem->setFinalized(true); + mAnalyticsItem->selfrecord(); + } + } + void gather(const AudioTrack *track); + private: + std::unique_ptr mAnalyticsItem; + }; + MediaMetrics mMediaMetrics; }; }; // namespace android diff --git a/media/libmedia/TypeConverter.cpp b/media/libmedia/TypeConverter.cpp index e6c8f9c1b6..9b06047972 100644 --- a/media/libmedia/TypeConverter.cpp +++ b/media/libmedia/TypeConverter.cpp @@ -277,6 +277,16 @@ const AudioModeConverter::Table AudioModeConverter::mTable[] = { TERMINATOR }; +template<> +const AudioContentTypeConverter::Table AudioContentTypeConverter::mTable[] = { + MAKE_STRING_FROM_ENUM(AUDIO_CONTENT_TYPE_UNKNOWN), + MAKE_STRING_FROM_ENUM(AUDIO_CONTENT_TYPE_SPEECH), + MAKE_STRING_FROM_ENUM(AUDIO_CONTENT_TYPE_MUSIC), + MAKE_STRING_FROM_ENUM(AUDIO_CONTENT_TYPE_MOVIE), + MAKE_STRING_FROM_ENUM(AUDIO_CONTENT_TYPE_SONIFICATION), + TERMINATOR +}; + template <> const UsageTypeConverter::Table UsageTypeConverter::mTable[] = { MAKE_STRING_FROM_ENUM(AUDIO_USAGE_UNKNOWN), diff --git a/media/libmedia/include/media/TypeConverter.h b/media/libmedia/include/media/TypeConverter.h index 84e22b1478..86f0d4c275 100644 --- a/media/libmedia/include/media/TypeConverter.h +++ b/media/libmedia/include/media/TypeConverter.h @@ -80,6 +80,11 @@ struct AudioModeTraits typedef audio_mode_t Type; typedef Vector Collection; }; +struct AudioContentTraits +{ + typedef audio_content_type_t Type; + typedef Vector Collection; +}; struct UsageTraits { typedef audio_usage_t Type; @@ -226,6 +231,7 @@ typedef TypeConverter ChannelIndexConverter; typedef TypeConverter GainModeConverter; typedef TypeConverter StreamTypeConverter; typedef TypeConverter AudioModeConverter; +typedef TypeConverter AudioContentTypeConverter; typedef TypeConverter UsageTypeConverter; typedef TypeConverter SourceTypeConverter; @@ -240,6 +246,7 @@ template<> const ChannelIndexConverter::Table ChannelIndexConverter::mTable[]; template<> const GainModeConverter::Table GainModeConverter::mTable[]; template<> const StreamTypeConverter::Table StreamTypeConverter::mTable[]; template<> const AudioModeConverter::Table AudioModeConverter::mTable[]; +template<> const AudioContentTypeConverter::Table AudioContentTypeConverter::mTable[]; template<> const UsageTypeConverter::Table UsageTypeConverter::mTable[]; template<> const SourceTypeConverter::Table SourceTypeConverter::mTable[];