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

Commit 515eb097 authored by jiabin's avatar jiabin Committed by Jiabin Huang
Browse files

MediaMetrics: Collect report for aaudio stream

Test: adb shell dumpsys media.metrics
Test: statsd_testdrive
Bug: 171345744
Change-Id: I71f5ab0d80334c26ac709df9853fcded4a519ab7
parent 40e3a7a2
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -56,6 +56,12 @@ AudioStream::~AudioStream() {

    ALOGE_IF(mHasThread, "%s() callback thread never join()ed", __func__);

    if (!mMetricsId.empty()) {
        android::mediametrics::LogItem(mMetricsId)
                .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_ENDAAUDIOSTREAM)
                .record();
    }

    // If the stream is deleted when OPEN or in use then audio resources will leak.
    // This would indicate an internal error. So we want to find this ASAP.
    LOG_ALWAYS_FATAL_IF(!(getState() == AAUDIO_STREAM_STATE_CLOSED
+1 −0
Original line number Diff line number Diff line
@@ -170,6 +170,7 @@
#define AMEDIAMETRICS_PROP_EVENT_VALUE_CTOR       "ctor"
#define AMEDIAMETRICS_PROP_EVENT_VALUE_DISCONNECT "disconnect"
#define AMEDIAMETRICS_PROP_EVENT_VALUE_DTOR       "dtor"
#define AMEDIAMETRICS_PROP_EVENT_VALUE_ENDAAUDIOSTREAM "endAAudioStream" // AAudioStream
#define AMEDIAMETRICS_PROP_EVENT_VALUE_ENDAUDIOINTERVALGROUP "endAudioIntervalGroup"
#define AMEDIAMETRICS_PROP_EVENT_VALUE_FLUSH      "flush"  // AudioTrack
#define AMEDIAMETRICS_PROP_EVENT_VALUE_INVALIDATE "invalidate" // server track, record
+142 −0
Original line number Diff line number Diff line
@@ -136,6 +136,25 @@ static constexpr const char * const AudioDeviceConnectionFields[] = {
    "connection_count",
};

// static constexpr const char * const AAudioStreamFields[] {
//     "mediametrics_aaudiostream_reported",
//     "caller_name",
//     "path",
//     "direction",
//     "frames_per_burst",
//     "buffer_size",
//     "buffer_capacity",
//     "channel_count",
//     "total_frames_transferred",
//     "perf_mode_requested",
//     "perf_mode_actual",
//     "sharing",
//     "xrun_count",
//     "device_type",
//     "format_app",
//     "format_device",
// };

/**
 * sendToStatsd is a helper method that sends the arguments to statsd
 * and returns a pair { result, summary_string }.
@@ -192,6 +211,24 @@ AudioAnalytics::AudioAnalytics()
                });
            }));

    // Handle legacy aaudio stream statistics
    mActions.addAction(
        AMEDIAMETRICS_KEY_PREFIX_AUDIO_TRACK "*." AMEDIAMETRICS_PROP_EVENT,
        std::string(AMEDIAMETRICS_PROP_EVENT_VALUE_ENDAAUDIOSTREAM),
        std::make_shared<AnalyticsActions::Function>(
            [this](const std::shared_ptr<const android::mediametrics::Item> &item) {
                mAAudioStreamInfo.endAAudioStream(item, AAudioStreamInfo::CALLER_PATH_LEGACY);
            }));

    // Handle mmap aaudio stream statistics
    mActions.addAction(
        AMEDIAMETRICS_KEY_PREFIX_AUDIO_STREAM "*." AMEDIAMETRICS_PROP_EVENT,
        std::string(AMEDIAMETRICS_PROP_EVENT_VALUE_ENDAAUDIOSTREAM),
        std::make_shared<AnalyticsActions::Function>(
            [this](const std::shared_ptr<const android::mediametrics::Item> &item) {
                mAAudioStreamInfo.endAAudioStream(item, AAudioStreamInfo::CALLER_PATH_MMAP);
            }));

    // Handle device use record statistics
    mActions.addAction(
        AMEDIAMETRICS_KEY_PREFIX_AUDIO_RECORD "*." AMEDIAMETRICS_PROP_EVENT,
@@ -843,4 +880,109 @@ void AudioAnalytics::DeviceConnection::expire() {
    }
}

void AudioAnalytics::AAudioStreamInfo::endAAudioStream(
        const std::shared_ptr<const android::mediametrics::Item> &item, CallerPath path) const {
    const std::string& key = item->getKey();

    std::string callerNameStr;
    mAudioAnalytics.mAnalyticsState->timeMachine().get(
            key, AMEDIAMETRICS_PROP_CALLERNAME, &callerNameStr);

    const auto callerName = types::lookup<types::CALLER_NAME, int32_t>(callerNameStr);

    std::string directionStr;
    mAudioAnalytics.mAnalyticsState->timeMachine().get(
            key, AMEDIAMETRICS_PROP_DIRECTION, &directionStr);
    const auto direction = types::lookup<types::AAUDIO_DIRECTION, int32_t>(directionStr);

    int32_t framesPerBurst = -1;
    mAudioAnalytics.mAnalyticsState->timeMachine().get(
            key, AMEDIAMETRICS_PROP_BURSTFRAMES, &framesPerBurst);

    int32_t bufferSizeInFrames = -1;
    mAudioAnalytics.mAnalyticsState->timeMachine().get(
            key, AMEDIAMETRICS_PROP_BUFFERSIZEFRAMES, &bufferSizeInFrames);

    int32_t bufferCapacityInFrames = -1;
    mAudioAnalytics.mAnalyticsState->timeMachine().get(
            key, AMEDIAMETRICS_PROP_BUFFERCAPACITYFRAMES, &bufferCapacityInFrames);

    int32_t channelCount = -1;
    mAudioAnalytics.mAnalyticsState->timeMachine().get(
            key, AMEDIAMETRICS_PROP_CHANNELCOUNT, &channelCount);

    int64_t totalFramesTransferred = -1;
    // TODO: log and get total frames transferred

    std::string perfModeRequestedStr;
    mAudioAnalytics.mAnalyticsState->timeMachine().get(
            key, AMEDIAMETRICS_PROP_PERFORMANCEMODE, &perfModeRequestedStr);
    const auto perfModeRequested =
            types::lookup<types::AAUDIO_PERFORMANCE_MODE, int32_t>(perfModeRequestedStr);

    int32_t perfModeActual = 0;
    // TODO: log and get actual performance mode

    std::string sharingModeStr;
    mAudioAnalytics.mAnalyticsState->timeMachine().get(
            key, AMEDIAMETRICS_PROP_SHARINGMODE, &sharingModeStr);
    const auto sharingMode = types::lookup<types::AAUDIO_SHARING_MODE, int32_t>(sharingModeStr);

    int32_t xrunCount = -1;
    mAudioAnalytics.mAnalyticsState->timeMachine().get(
            key, AMEDIAMETRICS_PROP_UNDERRUN, &xrunCount);

    std::string deviceType;
    // TODO: only routed device id is logged, but no device type

    int32_t formatApp = 0;
    // TODO: log format from app

    std::string formatDeviceStr;
    mAudioAnalytics.mAnalyticsState->timeMachine().get(
            key, AMEDIAMETRICS_PROP_ENCODING, &formatDeviceStr);
    const auto formatDevice = types::lookup<types::ENCODING, int32_t>(formatDeviceStr);

    LOG(LOG_LEVEL) << "key:" << key
            << " caller_name:" << callerName << "(" << callerNameStr << ")"
            << " path:" << path
            << " direction:" << direction << "(" << directionStr << ")"
            << " frames_per_burst:" << framesPerBurst
            << " buffer_size:" << bufferSizeInFrames
            << " buffer_capacity:" << bufferCapacityInFrames
            << " channel_count:" << channelCount
            << " total_frames_transferred:" << totalFramesTransferred
            << " perf_mode_requested:" << perfModeRequested << "(" << perfModeRequestedStr << ")"
            << " perf_mode_actual:" << perfModeActual
            << " sharing:" << sharingMode << "(" << sharingModeStr << ")"
            << " xrun_count:" << xrunCount
            << " device_type:" << deviceType
            << " format_app:" << formatApp
            << " format_device: " << formatDevice << "(" << formatDeviceStr << ")";

    // TODO: send the metric to statsd when the proto is ready
    // if (mAudioAnalytics.mDeliverStatistics) {
    //     const auto [ result, str ] = sendToStatsd(AAudioStreamFields,
    //             CONDITION(android::util::MEDIAMETRICS_AAUDIOSTREAM_REPORTED)
    //             , callerName
    //             , path
    //             , direction
    //             , framesPerBurst
    //             , bufferSizeInFrames
    //             , bufferCapacityInFrames
    //             , channelCount
    //             , totalFramesTransferred
    //             , perfModeRequested
    //             , perfModeActual
    //             , sharingMode
    //             , xrunCount
    //             , deviceType.c_str()
    //             , formatApp
    //             , formatDevice
    //             );
    //     ALOGV("%s: statsd %s", __func__, str.c_str());
    //     mAudioAnalytics.mStatsdLog.log("%s", str.c_str());
    // }
}

} // namespace android::mediametrics
+23 −0
Original line number Diff line number Diff line
@@ -189,6 +189,29 @@ private:
        int32_t mA2dpConnectionUnknowns GUARDED_BY(mLock) = 0;
    } mDeviceConnection{*this};

    // AAudioStreamInfo is a nested class which collect aaudio stream info from both client and
    // server side.
    class AAudioStreamInfo {
    public:
        // All the enum here must be kept the same as the ones defined in atoms.proto
        enum CallerPath {
            CALLER_PATH_UNKNOWN = 0,
            CALLER_PATH_LEGACY = 1,
            CALLER_PATH_MMAP = 2,
        };

        explicit AAudioStreamInfo(AudioAnalytics &audioAnalytics)
            : mAudioAnalytics(audioAnalytics) {}

        void endAAudioStream(
                const std::shared_ptr<const android::mediametrics::Item> &item,
                CallerPath path) const;

    private:

        AudioAnalytics &mAudioAnalytics;
    } mAAudioStreamInfo{*this};

    AudioPowerUsage mAudioPowerUsage{this};
};

+100 −0
Original line number Diff line number Diff line
@@ -154,6 +154,40 @@ const std::unordered_map<std::string, int32_t>& getAudioTrackTraitsMap() {
    return map;
}

const std::unordered_map<std::string, int32_t>& getAAudioDirection() {
    // DO NOT MODIFY VALUES(OK to add new ones).
    // This may be found in frameworks/av/media/libaaudio/include/aaudio/AAudio.h
    static std::unordered_map<std::string, int32_t> map {
        // UNKNOWN is -1
        {"AAUDIO_DIRECTION_OUTPUT",    0},
        {"AAUDIO_DIRECTION_INPUT",     1},
    };
    return map;
}

const std::unordered_map<std::string, int32_t>& getAAudioPerformanceMode() {
    // DO NOT MODIFY VALUES(OK to add new ones).
    // This may be found in frameworks/av/media/libaaudio/include/aaudio/AAudio.h
    static std::unordered_map<std::string, int32_t> map {
        // UNKNOWN is -1
        {"AAUDIO_PERFORMANCE_MODE_NONE",            10},
        {"AAUDIO_PERFORMANCE_MODE_POWER_SAVING",    11},
        {"AAUDIO_PERFORMANCE_MODE_LOW_LATENCY",     12},
    };
    return map;
}

const std::unordered_map<std::string, int32_t>& getAAudioSharingMode() {
    // DO NOT MODIFY VALUES(OK to add new ones).
    // This may be found in frameworks/av/media/libaaudio/include/aaudio/AAudio.h
    static std::unordered_map<std::string, int32_t> map {
        // UNKNOWN is -1
        {"AAUDIO_SHARING_MODE_EXCLUSIVE",    0},
        {"AAUDIO_SHARING_MODE_SHARED",       1},
    };
    return map;
}

// Helper: Create the corresponding int32 from string flags split with '|'.
template <typename Traits>
int32_t int32FromFlags(const std::string &flags)
@@ -433,4 +467,70 @@ int32_t lookup<TRACK_TRAITS>(const std::string &traits)
    return flagsFromMap(traits, getAudioTrackTraitsMap());
}

template <>
std::string lookup<AAUDIO_DIRECTION>(const std::string &direction)
{
    auto& map = getAAudioDirection();
    auto it = map.find(direction);
    if (it == map.end()) {
        return "";
    }
    return direction;
}

template <>
int32_t lookup<AAUDIO_DIRECTION>(const std::string &direction)
{
    auto& map = getAAudioDirection();
    auto it = map.find(direction);
    if (it == map.end()) {
        return -1; // return unknown
    }
    return it->second;
}

template <>
std::string lookup<AAUDIO_PERFORMANCE_MODE>(const std::string &performanceMode)
{
    auto& map = getAAudioPerformanceMode();
    auto it = map.find(performanceMode);
    if (it == map.end()) {
        return "";
    }
    return performanceMode;
}

template <>
int32_t lookup<AAUDIO_PERFORMANCE_MODE>(const std::string &performanceMode)
{
    auto& map = getAAudioPerformanceMode();
    auto it = map.find(performanceMode);
    if (it == map.end()) {
        return -1; // return unknown
    }
    return it->second;
}

template <>
std::string lookup<AAUDIO_SHARING_MODE>(const std::string &sharingMode)
{
    auto& map = getAAudioSharingMode();
    auto it = map.find(sharingMode);
    if (it == map.end()) {
        return "";
    }
    return sharingMode;
}

template <>
int32_t lookup<AAUDIO_SHARING_MODE>(const std::string &sharingMode)
{
    auto& map = getAAudioSharingMode();
    auto it = map.find(sharingMode);
    if (it == map.end()) {
        return -1; // return unknown
    }
    return it->second;
}

} // namespace android::mediametrics::types
Loading