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

Commit b1df0092 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "MediaMetrics: Fix inaccurate attribution of thread device" into tm-qpr-dev

parents 4ceb1428 76adef79
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -87,6 +87,7 @@
#define AMEDIAMETRICS_PROP_PREFIX_EFFECTIVE "effective."
#define AMEDIAMETRICS_PROP_PREFIX_HAL       "hal."
#define AMEDIAMETRICS_PROP_PREFIX_HAPTIC    "haptic."
#define AMEDIAMETRICS_PROP_PREFIX_LAST      "last."
#define AMEDIAMETRICS_PROP_PREFIX_SERVER    "server."

// Properties within mediametrics are string constants denoted by
+8 −1
Original line number Diff line number Diff line
@@ -148,7 +148,14 @@ private:
            item.set(AMEDIAMETRICS_PROP_CUMULATIVETIMENS, mCumulativeTimeNs)
                .set(AMEDIAMETRICS_PROP_DEVICETIMENS, mDeviceTimeNs)
                .set(AMEDIAMETRICS_PROP_EVENT, eventName)
                .set(AMEDIAMETRICS_PROP_INTERVALCOUNT, (int32_t)mIntervalCount);
                .set(AMEDIAMETRICS_PROP_INTERVALCOUNT, (int32_t)mIntervalCount)
                // we set "last" device to indicate the device the group was
                // associated with (because a createPatch which is logged in ThreadMetrics
                // could have changed the device).
                .set(mIsOut
                        ? AMEDIAMETRICS_PROP_PREFIX_LAST AMEDIAMETRICS_PROP_OUTPUTDEVICES
                        : AMEDIAMETRICS_PROP_PREFIX_LAST AMEDIAMETRICS_PROP_INPUTDEVICES,
                        mDevices.c_str());
            if (mDeviceLatencyMs.getN() > 0) {
                item.set(AMEDIAMETRICS_PROP_DEVICELATENCYMS, mDeviceLatencyMs.getMean());
            }
+63 −67
Original line number Diff line number Diff line
@@ -788,15 +788,9 @@ void AudioAnalytics::DeviceUse::endAudioIntervalGroup(
    int32_t frameCount = 0;
    mAudioAnalytics.mAnalyticsState->timeMachine().get(
            key, AMEDIAMETRICS_PROP_FRAMECOUNT, &frameCount);
    std::string inputDevicePairs;
    mAudioAnalytics.mAnalyticsState->timeMachine().get(
            key, AMEDIAMETRICS_PROP_INPUTDEVICES, &inputDevicePairs);
    int32_t intervalCount = 0;
    mAudioAnalytics.mAnalyticsState->timeMachine().get(
            key, AMEDIAMETRICS_PROP_INTERVALCOUNT, &intervalCount);
    std::string outputDevicePairs;
    mAudioAnalytics.mAnalyticsState->timeMachine().get(
            key, AMEDIAMETRICS_PROP_OUTPUTDEVICES, &outputDevicePairs);
    int32_t sampleRate = 0;
    mAudioAnalytics.mAnalyticsState->timeMachine().get(
            key, AMEDIAMETRICS_PROP_SAMPLERATE, &sampleRate);
@@ -804,53 +798,16 @@ void AudioAnalytics::DeviceUse::endAudioIntervalGroup(
    mAudioAnalytics.mAnalyticsState->timeMachine().get(
            key, AMEDIAMETRICS_PROP_FLAGS, &flags);

    // We may have several devices.
    // Accumulate the bit flags for input and output devices.
    std::stringstream oss;
    long_enum_type_t outputDeviceBits{};
    {   // compute outputDevices
        const auto devaddrvec = stringutils::getDeviceAddressPairs(outputDevicePairs);
        for (const auto& [device, addr] : devaddrvec) {
            if (oss.tellp() > 0) oss << "|";  // delimit devices with '|'.
            oss << device;
            outputDeviceBits += types::lookup<types::OUTPUT_DEVICE, long_enum_type_t>(device);
        }
    }
    const std::string outputDevices = oss.str();

    std::stringstream iss;
    long_enum_type_t inputDeviceBits{};
    {   // compute inputDevices
        const auto devaddrvec = stringutils::getDeviceAddressPairs(inputDevicePairs);
        for (const auto& [device, addr] : devaddrvec) {
            if (iss.tellp() > 0) iss << "|";  // delimit devices with '|'.
            iss << device;
            inputDeviceBits += types::lookup<types::INPUT_DEVICE, long_enum_type_t>(device);
        }
    }
    const std::string inputDevices = iss.str();

    // Get connected device name if from bluetooth.
    bool isBluetooth = false;

    std::string inputDeviceNames;  // not filled currently.
    std::string outputDeviceNames;
    if (outputDevices.find("AUDIO_DEVICE_OUT_BLUETOOTH") != std::string::npos) {
        isBluetooth = true;
        outputDeviceNames = SUPPRESSED;
#if 0   // TODO(b/161554630) sanitize name
        mAudioAnalytics.mAnalyticsState->timeMachine().get(
            "audio.device.bt_a2dp", AMEDIAMETRICS_PROP_NAME, &outputDeviceNames);
        // Remove | if present
        stringutils::replace(outputDeviceNames, "|", '?');
        if (outputDeviceNames.size() > STATSD_DEVICE_NAME_MAX_LENGTH) {
            outputDeviceNames.resize(STATSD_DEVICE_NAME_MAX_LENGTH); // truncate
        }
#endif
    }

    switch (itemType) {
    case RECORD: {
        std::string inputDevicePairs;
        mAudioAnalytics.mAnalyticsState->timeMachine().get(
                key, AMEDIAMETRICS_PROP_INPUTDEVICES, &inputDevicePairs);

        const auto [ inputDeviceStatsd, inputDevices ] =
                stringutils::parseInputDevicePairs(inputDevicePairs);
        const std::string inputDeviceNames;  // not filled currently.

        std::string callerName;
        const bool clientCalled = mAudioAnalytics.mAnalyticsState->timeMachine().get(
                key, AMEDIAMETRICS_PROP_CALLERNAME, &callerName) == OK;
@@ -886,7 +843,7 @@ void AudioAnalytics::DeviceUse::endAudioIntervalGroup(

        LOG(LOG_LEVEL) << "key:" << key
              << " id:" << id
              << " inputDevices:" << inputDevices << "(" << inputDeviceBits
              << " inputDevices:" << inputDevices << "(" << inputDeviceStatsd
              << ") inputDeviceNames:" << inputDeviceNames
              << " deviceTimeNs:" << deviceTimeNs
              << " encoding:" << encoding << "(" << encodingForStats
@@ -904,7 +861,7 @@ void AudioAnalytics::DeviceUse::endAudioIntervalGroup(
                && mAudioAnalytics.mDeliverStatistics) {
            const auto [ result, str ] = sendToStatsd(AudioRecordDeviceUsageFields,
                    CONDITION(android::util::MEDIAMETRICS_AUDIORECORDDEVICEUSAGE_REPORTED)
                    , ENUM_EXTRACT(inputDeviceBits)
                    , ENUM_EXTRACT(inputDeviceStatsd)
                    , inputDeviceNames.c_str()
                    , deviceTimeNs
                    , ENUM_EXTRACT(encodingForStats)
@@ -933,6 +890,25 @@ void AudioAnalytics::DeviceUse::endAudioIntervalGroup(
                key, AMEDIAMETRICS_PROP_UNDERRUN, &underrun);

        const bool isInput = types::isInputThreadType(type);

        // get device information
        std::string devicePairs;
        std::string deviceStatsd;
        std::string devices;
        std::string deviceNames;
        if (isInput) {
            // Note we get the "last" device which is the one associated with group.
            item->get(AMEDIAMETRICS_PROP_PREFIX_LAST AMEDIAMETRICS_PROP_INPUTDEVICES,
                    &devicePairs);
            std::tie(deviceStatsd, devices) = stringutils::parseInputDevicePairs(devicePairs);
        } else {
            // Note we get the "last" device which is the one associated with group.
            item->get(AMEDIAMETRICS_PROP_PREFIX_LAST AMEDIAMETRICS_PROP_OUTPUTDEVICES,
                    &devicePairs);
            std::tie(deviceStatsd, devices) = stringutils::parseOutputDevicePairs(devicePairs);
            deviceNames = mAudioAnalytics.getDeviceNamesFromOutputDevices(devices);
        }

        const auto encodingForStats = types::lookup<types::ENCODING, short_enum_type_t>(encoding);
        const auto flagsForStats =
                (isInput ? types::lookup<types::INPUT_FLAG, short_enum_type_t>(flags)
@@ -941,10 +917,8 @@ void AudioAnalytics::DeviceUse::endAudioIntervalGroup(

         LOG(LOG_LEVEL) << "key:" << key
              << " id:" << id
              << " inputDevices:" << inputDevices << "(" << inputDeviceBits
              << ") outputDevices:" << outputDevices << "(" << outputDeviceBits
              << ") inputDeviceNames:" << inputDeviceNames
              << " outputDeviceNames:" << outputDeviceNames
              << " devices:" << devices << "(" << deviceStatsd
              << ") deviceNames:" << deviceNames
              << " deviceTimeNs:" << deviceTimeNs
              << " encoding:" << encoding << "(" << encodingForStats
              << ") frameCount:" << frameCount
@@ -957,8 +931,8 @@ void AudioAnalytics::DeviceUse::endAudioIntervalGroup(
        if (mAudioAnalytics.mDeliverStatistics) {
            const auto [ result, str ] = sendToStatsd(AudioThreadDeviceUsageFields,
                CONDITION(android::util::MEDIAMETRICS_AUDIOTHREADDEVICEUSAGE_REPORTED)
                , isInput ? ENUM_EXTRACT(inputDeviceBits) : ENUM_EXTRACT(outputDeviceBits)
                , isInput ? inputDeviceNames.c_str() : outputDeviceNames.c_str()
                , ENUM_EXTRACT(deviceStatsd)
                , deviceNames.c_str()
                , deviceTimeNs
                , ENUM_EXTRACT(encodingForStats)
                , frameCount
@@ -974,6 +948,15 @@ void AudioAnalytics::DeviceUse::endAudioIntervalGroup(
        }
    } break;
    case TRACK: {
        std::string outputDevicePairs;
        mAudioAnalytics.mAnalyticsState->timeMachine().get(
                key, AMEDIAMETRICS_PROP_OUTPUTDEVICES, &outputDevicePairs);

        const auto [ outputDeviceStatsd, outputDevices ] =
                stringutils::parseOutputDevicePairs(outputDevicePairs);
        const std::string outputDeviceNames =
                mAudioAnalytics.getDeviceNamesFromOutputDevices(outputDevices);

        std::string callerName;
        const bool clientCalled = mAudioAnalytics.mAnalyticsState->timeMachine().get(
                key, AMEDIAMETRICS_PROP_CALLERNAME, &callerName) == OK;
@@ -1041,7 +1024,7 @@ void AudioAnalytics::DeviceUse::endAudioIntervalGroup(

        LOG(LOG_LEVEL) << "key:" << key
              << " id:" << id
              << " outputDevices:" << outputDevices << "(" << outputDeviceBits
              << " outputDevices:" << outputDevices << "(" << outputDeviceStatsd
              << ") outputDeviceNames:" << outputDeviceNames
              << " deviceTimeNs:" << deviceTimeNs
              << " encoding:" << encoding << "(" << encodingForStats
@@ -1068,7 +1051,7 @@ void AudioAnalytics::DeviceUse::endAudioIntervalGroup(
                && mAudioAnalytics.mDeliverStatistics) {
            const auto [ result, str ] = sendToStatsd(AudioTrackDeviceUsageFields,
                    CONDITION(android::util::MEDIAMETRICS_AUDIOTRACKDEVICEUSAGE_REPORTED)
                    , ENUM_EXTRACT(outputDeviceBits)
                    , ENUM_EXTRACT(outputDeviceStatsd)
                    , outputDeviceNames.c_str()
                    , deviceTimeNs
                    , ENUM_EXTRACT(encodingForStats)
@@ -1095,11 +1078,6 @@ void AudioAnalytics::DeviceUse::endAudioIntervalGroup(
        }
        } break;
    }

    // Report this as needed.
    if (isBluetooth) {
        // report this for Bluetooth
    }
}

// DeviceConnection helper class.
@@ -1732,4 +1710,22 @@ std::pair<std::string, int32_t> AudioAnalytics::Spatializer::dump(
    return { s, n };
}

// This method currently suppresses the name.
std::string AudioAnalytics::getDeviceNamesFromOutputDevices(std::string_view devices) const {
    std::string deviceNames;
    if (stringutils::hasBluetoothOutputDevice(devices)) {
        deviceNames = SUPPRESSED;
#if 0   // TODO(b/161554630) sanitize name
        mAudioAnalytics.mAnalyticsState->timeMachine().get(
            "audio.device.bt_a2dp", AMEDIAMETRICS_PROP_NAME, &deviceNames);
        // Remove | if present
        stringutils::replace(deviceNames, "|", '?');
        if (deviceNames.size() > STATSD_DEVICE_NAME_MAX_LENGTH) {
            deviceNames.resize(STATSD_DEVICE_NAME_MAX_LENGTH); // truncate
        }
#endif
    }
    return deviceNames;
}

} // namespace android::mediametrics
+28 −0
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@

#include "StringUtils.h"

#include "AudioTypes.h"

namespace android::mediametrics::stringutils {

std::string tokenizer(std::string::const_iterator& it,
@@ -99,4 +101,30 @@ size_t replace(std::string &str, const char *targetChars, const char replaceChar
    return replaced;
}

template <types::AudioEnumCategory CATEGORY>
std::pair<std::string /* external statsd */, std::string /* internal */>
parseDevicePairs(const std::string& devicePairs) {
    std::pair<std::string, std::string> result{};
    const auto devaddrvec = stringutils::getDeviceAddressPairs(devicePairs);
    for (const auto& [device, addr] : devaddrvec) { // addr ignored for now.
        if (!result.second.empty()) {
            result.second.append("|"); // delimit devices with '|'.
            result.first.append("|");
        }
        result.second.append(device);
        result.first.append(types::lookup<CATEGORY, std::string>(device));
    }
    return result;
}

std::pair<std::string /* external statsd */, std::string /* internal */>
parseOutputDevicePairs(const std::string& devicePairs) {
    return parseDevicePairs<types::OUTPUT_DEVICE>(devicePairs);
}

std::pair<std::string /* external statsd */, std::string /* internal */>
parseInputDevicePairs(const std::string& devicePairs) {
    return parseDevicePairs<types::INPUT_DEVICE>(devicePairs);
}

} // namespace android::mediametrics::stringutils
+7 −0
Original line number Diff line number Diff line
@@ -161,6 +161,13 @@ private:
     */
    std::string getThreadFromTrack(const std::string& track) const;

    /**
     * return the device name, if present.
     *
     * This is currently enabled only for Bluetooth output devices.
     */
    std::string getDeviceNamesFromOutputDevices(std::string_view devices) const;

    const bool mDeliverStatistics;

    // Actions is individually locked
Loading