Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 88394301 authored by Ray Essick's avatar Ray Essick
Browse files

add getMetrics() apis for AudioTrack and AudioRecord

add getMetrics() method to access media.metrics for AudioTrack and
AudioRecord.

Bug: 72179020
Bug: 72178968
Test: tweaked CTS
Change-Id: Id69862887b8b58655f59057e06f96b20a8e7d332
parent 03570a65
Loading
Loading
Loading
Loading
+27 −2
Original line number Diff line number Diff line
@@ -77,22 +77,47 @@ static std::string audioFormatTypeString(audio_format_t value) {
    return rawbuffer;
}

static std::string audioSourceString(audio_source_t value) {
    std::string source;
    if (SourceTypeConverter::toString(value, source)) {
        return source;
    }
    char rawbuffer[16];  // room for "%d"
    snprintf(rawbuffer, sizeof(rawbuffer), "%d", value);
    return rawbuffer;
}

void AudioRecord::MediaMetrics::gather(const AudioRecord *record)
{
    // key for media statistics is defined in the header
    // attrs for media statistics
    static constexpr char kAudioRecordChannelCount[] = "android.media.audiorecord.channels";
    static constexpr char kAudioRecordFormat[] = "android.media.audiorecord.format";
    static constexpr char kAudioRecordEncoding[] = "android.media.audiorecord.encoding";
    static constexpr char kAudioRecordLatency[] = "android.media.audiorecord.latency";
    static constexpr char kAudioRecordSampleRate[] = "android.media.audiorecord.samplerate";
    static constexpr char kAudioRecordSource[] = "android.media.audiotrack.source";

    // constructor guarantees mAnalyticsItem is valid

    mAnalyticsItem->setInt32(kAudioRecordLatency, record->mLatency);
    mAnalyticsItem->setInt32(kAudioRecordSampleRate, record->mSampleRate);
    mAnalyticsItem->setInt32(kAudioRecordChannelCount, record->mChannelCount);
    mAnalyticsItem->setCString(kAudioRecordFormat,
    mAnalyticsItem->setCString(kAudioRecordEncoding,
                               audioFormatTypeString(record->mFormat).c_str());
    mAnalyticsItem->setCString(kAudioRecordSource,
                               audioSourceString(record->mAttributes.source).c_str());
}

// hand the user a snapshot of the metrics.
status_t AudioRecord::getMetrics(MediaAnalyticsItem * &item)
{
    mMediaMetrics.gather(this);
    MediaAnalyticsItem *tmp = mMediaMetrics.dup();
    if (tmp == nullptr) {
        return BAD_VALUE;
    }
    item = tmp;
    return NO_ERROR;
}

AudioRecord::AudioRecord(const String16 &opPackageName)
+19 −7
Original line number Diff line number Diff line
@@ -189,22 +189,23 @@ void AudioTrack::MediaMetrics::gather(const AudioTrack *track)
    static constexpr char kAudioTrackUsage[] = "android.media.audiotrack.usage";
    static constexpr char kAudioTrackSampleRate[] = "android.media.audiotrack.samplerate";
    static constexpr char kAudioTrackChannelMask[] = "android.media.audiotrack.channelmask";
#if 0
    // XXX: disabled temporarily for b/72027185
    static constexpr char kAudioTrackUnderrunFrames[] = "android.media.audiotrack.underrunframes";
#endif
    static constexpr char kAudioTrackStartupGlitch[] = "android.media.audiotrack.glitch.startup";

    // only if we're in a good state...
    // XXX: shall we gather alternative info if failing?
    const status_t lstatus = track->initCheck();
    if (lstatus != NO_ERROR) {
        ALOGD("no metrics gathered, track status=%d", (int) lstatus);
        return;
    }

    // constructor guarantees mAnalyticsItem is valid

#if 0
    // XXX: disabled temporarily for b/72027185
    // must gather underrun info before cleaning mProxy information.
    const int32_t underrunFrames = track->getUnderrunFrames();
    if (underrunFrames != 0) {
        mAnalyticsItem->setInt32(kAudioTrackUnderrunFrames, underrunFrames);
    }
#endif

    if (track->mTimestampStartupGlitchReported) {
        mAnalyticsItem->setInt32(kAudioTrackStartupGlitch, 1);
@@ -223,6 +224,17 @@ void AudioTrack::MediaMetrics::gather(const AudioTrack *track)
    mAnalyticsItem->setInt64(kAudioTrackChannelMask, track->mChannelMask);
}

// hand the user a snapshot of the metrics.
status_t AudioTrack::getMetrics(MediaAnalyticsItem * &item)
{
    mMediaMetrics.gather(this);
    MediaAnalyticsItem *tmp = mMediaMetrics.dup();
    if (tmp == nullptr) {
        return BAD_VALUE;
    }
    item = tmp;
    return NO_ERROR;
}

AudioTrack::AudioTrack()
    : mStatus(NO_INIT),
+6 −0
Original line number Diff line number Diff line
@@ -256,6 +256,11 @@ public:
     */
            uint32_t    getNotificationPeriodInFrames() const { return mNotificationFramesAct; }

    /*
     * return metrics information for the current instance.
     */
            status_t getMetrics(MediaAnalyticsItem * &item);

    /* After it's created the track is not active. Call start() to
     * make it active. If set, the callback will start being called.
     * If event is not AudioSystem::SYNC_EVENT_NONE, the capture start will be delayed until
@@ -703,6 +708,7 @@ private:
            }
        }
        void gather(const AudioRecord *record);
        MediaAnalyticsItem *dup() { return mAnalyticsItem->dup(); }
      private:
        std::unique_ptr<MediaAnalyticsItem> mAnalyticsItem;
    };
+6 −0
Original line number Diff line number Diff line
@@ -386,6 +386,11 @@ public:
    /* Return the static buffer specified in constructor or set(), or 0 for streaming mode */
            sp<IMemory> sharedBuffer() const { return mSharedBuffer; }

    /*
     * return metrics information for the current track.
     */
            status_t getMetrics(MediaAnalyticsItem * &item);

    /* After it's created the track is not active. Call start() to
     * make it active. If set, the callback will start being called.
     * If the track was previously paused, volume is ramped up over the first mix buffer.
@@ -1198,6 +1203,7 @@ private:
            }
        }
        void gather(const AudioTrack *track);
        MediaAnalyticsItem *dup() { return mAnalyticsItem->dup(); }
      private:
        std::unique_ptr<MediaAnalyticsItem> mAnalyticsItem;
    };