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

Commit 4442d049 authored by Andy Hung's avatar Andy Hung
Browse files

MediaMetricsService: Deliver Spatialization atoms to statsd

Test: adb shell dumpsys media.metrics
Test: statsd_testdrive
Bug: 233773341
Merged-In: If35e4feeef488079ddaab131e60d37d8460b4d5f
Change-Id: If35e4feeef488079ddaab131e60d37d8460b4d5f
(cherry picked from commit 8a7ecfff)
parent 93424649
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -111,6 +111,7 @@
// of suppressed in the Time Machine.
#define AMEDIAMETRICS_PROP_SUFFIX_CHAR_DUPLICATES_ALLOWED '#'

#define AMEDIAMETRICS_PROP_ADDRESS        "address"        // string, for example MAC address
#define AMEDIAMETRICS_PROP_ALLOWUID       "_allowUid"      // int32_t, allow client uid to post
#define AMEDIAMETRICS_PROP_AUDIOMODE      "audioMode"      // string (audio.flinger)
#define AMEDIAMETRICS_PROP_AUXEFFECTID    "auxEffectId"    // int32 (AudioTrack)
@@ -120,6 +121,8 @@
#define AMEDIAMETRICS_PROP_CALLERNAME     "callerName"     // string, eg. "aaudio"
#define AMEDIAMETRICS_PROP_CHANNELCOUNT   "channelCount"   // int32
#define AMEDIAMETRICS_PROP_CHANNELMASK    "channelMask"    // int32
#define AMEDIAMETRICS_PROP_CHANNELMASKS   "channelMasks"   // string with channelMask values
                                                           // separated by |.
#define AMEDIAMETRICS_PROP_CONTENTTYPE    "contentType"    // string attributes (AudioTrack)
#define AMEDIAMETRICS_PROP_CUMULATIVETIMENS "cumulativeTimeNs" // int64_t playback/record time
                                                           // since start
+11 −1
Original line number Diff line number Diff line
@@ -274,6 +274,16 @@ Spatializer::~Spatializer() {
    mHandler.clear();
}

static std::string channelMaskVectorToString(
        const std::vector<audio_channel_mask_t>& masks) {
    std::stringstream ss;
    for (const auto &mask : masks) {
        if (ss.tellp() != 0) ss << "|";
        ss << mask;
    }
    return ss.str();
}

status_t Spatializer::loadEngineConfiguration(sp<EffectHalInterface> effect) {
    ALOGV("%s", __func__);

@@ -363,7 +373,7 @@ status_t Spatializer::loadEngineConfiguration(sp<EffectHalInterface> effect) {
    }
    mediametrics::LogItem(mMetricsId)
        .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_CREATE)
        .set(AMEDIAMETRICS_PROP_CHANNELMASK, (int32_t)getMaxChannelMask(mChannelMasks))
        .set(AMEDIAMETRICS_PROP_CHANNELMASKS, channelMaskVectorToString(mChannelMasks))
        .set(AMEDIAMETRICS_PROP_LEVELS, aidl_utils::enumsToString(mLevels))
        .set(AMEDIAMETRICS_PROP_MODES, aidl_utils::enumsToString(mSpatializationModes))
        .set(AMEDIAMETRICS_PROP_HEADTRACKINGMODES, aidl_utils::enumsToString(mHeadTrackingModes))
+108 −15
Original line number Diff line number Diff line
@@ -240,6 +240,35 @@ static constexpr const char * const AAudioStreamFields[] {
    "sharing_requested",
};

static constexpr const char * HeadTrackerDeviceEnabledFields[] {
    "mediametrics_headtrackerdeviceenabled_reported",
    "type",
    "event",
    "enabled",
};

static constexpr const char * HeadTrackerDeviceSupportedFields[] {
    "mediametrics_headtrackerdevicesupported_reported",
    "type",
    "event",
    "supported",
};

static constexpr const char * SpatializerCapabilitiesFields[] {
    "mediametrics_spatializer_reported",
    "head_tracking_modes",
    "spatializer_levels",
    "spatializer_modes",
    "channel_masks",
};

static constexpr const char * SpatializerDeviceEnabledFields[] {
    "mediametrics_spatializerdeviceenabled_reported",
    "type",
    "event",
    "enabled",
};

/**
 * printFields is a helper method that prints the fields and corresponding values
 * in a human readable style.
@@ -1534,6 +1563,17 @@ std::pair<std::string, int32_t> AudioAnalytics::Health::dump(
    return { s, n };
}

// Classifies the setting event for statsd (use generated statsd enums.proto constants).
static int32_t classifySettingEvent(bool isSetAlready, bool withinBoot) {
    if (isSetAlready) {
        return util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__EVENT__SPATIALIZER_SETTING_EVENT_NORMAL;
    }
    if (withinBoot) {
        return util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__EVENT__SPATIALIZER_SETTING_EVENT_BOOT;
    }
    return util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__EVENT__SPATIALIZER_SETTING_EVENT_FIRST;
}

void AudioAnalytics::Spatializer::onEvent(
        const std::shared_ptr<const android::mediametrics::Item> &item)
{
@@ -1560,14 +1600,14 @@ void AudioAnalytics::Spatializer::onEvent(
        std::string modes;
        (void)item->get(AMEDIAMETRICS_PROP_MODES, &modes);

        int32_t channelMask = 0;
        (void)item->get(AMEDIAMETRICS_PROP_CHANNELMASK, &channelMask);
        std::string channelMasks;
        (void)item->get(AMEDIAMETRICS_PROP_CHANNELMASKS, &channelMasks);

        LOG(LOG_LEVEL) << "key:" << key
                << " headTrackingModes:" << headTrackingModes
                << " levels:" << levels
                << " modes:" << modes
                << " channelMask:" << channelMask
                << " channelMasks:" << channelMasks
                ;

        const std::vector<int32_t> headTrackingModesVector =
@@ -1576,18 +1616,39 @@ void AudioAnalytics::Spatializer::onEvent(
                types::vectorFromMap(levels, types::getSpatializerLevelMap());
        const std::vector<int32_t> modesVector =
                types::vectorFromMap(modes, types::getSpatializerModeMap());
        const std::vector<int64_t> channelMasksVector =
                types::channelMaskVectorFromString(channelMasks);

        const auto [ result, str ] = sendToStatsd(SpatializerCapabilitiesFields,
                CONDITION(android::util::MEDIAMETRICS_SPATIALIZERCAPABILITIES_REPORTED)
                , headTrackingModesVector
                , levelsVector
                , modesVector
                , channelMasksVector
                );

        // TODO: send to statsd
        mAudioAnalytics.mStatsdLog->log(
                android::util::MEDIAMETRICS_SPATIALIZERCAPABILITIES_REPORTED, str);

        std::lock_guard lg(mLock);
        if (mFirstCreateTimeNs == 0) {
            // Only update the create time once to prevent audioserver restart
            // from looking like a boot.
            mFirstCreateTimeNs = item->getTimestamp();
        }
        mSimpleLog.log("%s suffix: %s item: %s",
                __func__, suffix.c_str(), item->toString().c_str());
    } else {
        std::string subtype = suffix.substr(0, delim);
        if (subtype != "device") return; // not a device.

        std::string deviceType = suffix.substr(std::size("device.") - 1);
        const std::string deviceType = suffix.substr(std::size("device.") - 1);

        const int32_t deviceTypeStatsd =
                types::lookup<types::AUDIO_DEVICE_INFO_TYPE, int32_t>(deviceType);

        std::string address;
        (void)item->get(AMEDIAMETRICS_PROP_ADDRESS, &address);
        std::string enabled;
        (void)item->get(AMEDIAMETRICS_PROP_ENABLED, &enabled);
        std::string hasHeadTracker;
@@ -1598,35 +1659,67 @@ void AudioAnalytics::Spatializer::onEvent(
        std::lock_guard lg(mLock);

        // Validate from our cached state
        DeviceState& deviceState = mDeviceStateMap[deviceType];

        // Our deviceKey takes the device type and appends the address if any.
        // This distinguishes different wireless devices for the purposes of tracking.
        std::string deviceKey(deviceType);
        deviceKey.append("_").append(address);
        DeviceState& deviceState = mDeviceStateMap[deviceKey];

        // check whether the settings event is within a certain time of spatializer creation.
        const bool withinBoot =
                item->getTimestamp() - mFirstCreateTimeNs < kBootDurationThreshold;

        if (!enabled.empty()) {
            if (enabled != deviceState.enabled) {
                const int32_t settingEventStatsd =
                        classifySettingEvent(!deviceState.enabled.empty(), withinBoot);
                deviceState.enabled = enabled;
                const bool enabledStatsd = enabled == "true";
                // TODO: send to statsd
                (void)mAudioAnalytics;
                (void)enabledStatsd;
                const auto [ result, str ] = sendToStatsd(SpatializerDeviceEnabledFields,
                        CONDITION(android::util::MEDIAMETRICS_SPATIALIZERDEVICEENABLED_REPORTED)
                        , deviceTypeStatsd
                        , settingEventStatsd
                        , enabledStatsd
                        );
                mAudioAnalytics.mStatsdLog->log(
                        android::util::MEDIAMETRICS_SPATIALIZERDEVICEENABLED_REPORTED, str);
            }
        }
        if (!hasHeadTracker.empty()) {
            if (hasHeadTracker != deviceState.hasHeadTracker) {
                const int32_t settingEventStatsd =
                        classifySettingEvent(!deviceState.hasHeadTracker.empty(), withinBoot);
                deviceState.hasHeadTracker = hasHeadTracker;
                const bool supportedStatsd = hasHeadTracker == "true";
                // TODO: send to statsd
                (void)supportedStatsd;
                const auto [ result, str ] = sendToStatsd(HeadTrackerDeviceSupportedFields,
                        CONDITION(android::util::MEDIAMETRICS_HEADTRACKERDEVICESUPPORTED_REPORTED)
                        , deviceTypeStatsd
                        , settingEventStatsd
                        , supportedStatsd
                        );
                mAudioAnalytics.mStatsdLog->log(
                        android::util::MEDIAMETRICS_HEADTRACKERDEVICESUPPORTED_REPORTED, str);
            }
        }
        if (!headTrackerEnabled.empty()) {
            if (headTrackerEnabled != deviceState.headTrackerEnabled) {
                const int32_t settingEventStatsd =
                        classifySettingEvent(!deviceState.headTrackerEnabled.empty(), withinBoot);
                deviceState.headTrackerEnabled = headTrackerEnabled;
                const bool enabledStatsd = headTrackerEnabled == "true";
                // TODO: send to statsd
                (void)enabledStatsd;
                const auto [ result, str ] = sendToStatsd(HeadTrackerDeviceEnabledFields,
                        CONDITION(android::util::MEDIAMETRICS_HEADTRACKERDEVICEENABLED_REPORTED)
                        , deviceTypeStatsd
                        , settingEventStatsd
                        , enabledStatsd
                        );
                mAudioAnalytics.mStatsdLog->log(
                        android::util::MEDIAMETRICS_HEADTRACKERDEVICEENABLED_REPORTED, str);
            }
        }
        mSimpleLog.log("%s deviceType: %s item: %s",
                __func__, deviceType.c_str(), item->toString().c_str());
        mSimpleLog.log("%s deviceKey: %s item: %s",
                __func__, deviceKey.c_str(), item->toString().c_str());
    }
}

+68 −0
Original line number Diff line number Diff line
@@ -179,6 +179,50 @@ const std::unordered_map<std::string, int32_t>& getAudioDeviceOutCompactMap() {
    return map;
}

// A map for the Java AudioDeviceInfo types.
// This uses generated statsd enums.proto constants.
const std::unordered_map<std::string, int32_t>& getAudioDeviceInfoTypeMap() {
    // DO NOT MODIFY VALUES (OK to add new ones).
    static std::unordered_map<std::string, int32_t> map{
        {"unknown", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_UNKNOWN},
        {"earpiece", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_BUILTIN_EARPIECE},
        {"speaker", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_BUILTIN_SPEAKER},
        {"headset", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_WIRED_HEADSET},
        {"headphone", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_WIRED_HEADPHONES}, // sic
        {"bt_sco", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_BLUETOOTH_SCO},
        {"bt_sco_hs", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_BLUETOOTH_SCO},
        {"bt_sco_carkit", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_BLUETOOTH_SCO},
        {"bt_a2dp", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_BLUETOOTH_A2DP},
        {"bt_a2dp_hp", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_BLUETOOTH_A2DP},
        {"bt_a2dp_spk", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_BLUETOOTH_A2DP},
        {"aux_digital", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_HDMI},
        {"hdmi", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_HDMI},
        {"analog_dock", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_DOCK},
        {"digital_dock", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_DOCK},
        {"usb_accessory", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_USB_ACCESSORY},
        {"usb_device", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_USB_DEVICE},
        {"usb_headset", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_USB_HEADSET},
        {"remote_submix", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_REMOTE_SUBMIX},
        {"telephony_tx", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_TELEPHONY},
        {"line", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_LINE_ANALOG},
        {"hdmi_arc", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_HDMI_ARC},
        {"hdmi_earc", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_HDMI_EARC},
        {"spdif", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_LINE_DIGITAL},
        {"fm_transmitter", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_FM},
        {"aux_line", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_AUX_LINE},
        {"speaker_safe", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_BUILTIN_SPEAKER_SAFE},
        {"ip", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_IP},
        {"bus", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_BUS},
        {"proxy", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_UNKNOWN /* AUDIO_DEVICE_INFO_TYPE_PROXY */},
        {"hearing_aid_out", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_HEARING_AID},
        {"echo_canceller", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_ECHO_REFERENCE}, // sic
        {"ble_headset", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_BLE_HEADSET},
        {"ble_speaker", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_BLE_SPEAKER},
        {"ble_broadcast", util::MEDIAMETRICS_SPATIALIZER_DEVICE_ENABLED_REPORTED__TYPE__AUDIO_DEVICE_INFO_TYPE_BLE_BROADCAST},
    };
    return map;
}

const std::unordered_map<std::string, int32_t>& getAudioThreadTypeMap() {
    // DO NOT MODIFY VALUES (OK to add new ones).
    // This may be found in frameworks/av/services/audioflinger/Threads.h
@@ -381,6 +425,19 @@ std::vector<int32_t> vectorFromMap(
    return v;
}

std::vector<int64_t> channelMaskVectorFromString(const std::string &s)
{
    std::vector<int64_t> v;

    const auto result = stringutils::split(s, "|");
    for (const auto &mask : result) {
        // 0 if undetected or if actually 0.
        int64_t int64Mask = strtoll(mask.c_str(), nullptr, 0);
        v.push_back(int64Mask);
    }
    return v;
}

template <>
int32_t lookup<CONTENT_TYPE>(const std::string &contentType)
{
@@ -535,6 +592,17 @@ std::string lookup<OUTPUT_DEVICE>(const std::string &outputDevice)
    return stringFromFlags<OutputDeviceTraits>(outputDevice, sizeof("AUDIO_DEVICE_OUT"));
}

template <>
int32_t lookup<AUDIO_DEVICE_INFO_TYPE>(const std::string& audioDeviceInfoType)
{
    auto& map = getAudioDeviceInfoTypeMap();
    auto it = map.find(audioDeviceInfoType);
    if (it == map.end()) {
        return 0;
    }
    return it->second;
}

template <>
int32_t lookup<CALLER_NAME>(const std::string &callerName)
{
+2 −1
Original line number Diff line number Diff line
@@ -349,8 +349,9 @@ private:
        };

        AudioAnalytics& mAudioAnalytics;

        static constexpr int64_t kBootDurationThreshold = 120 /* seconds */ * 1e9;
        mutable std::mutex mLock;
        int64_t mFirstCreateTimeNs GUARDED_BY(mLock) = 0;
        std::map<std::string, DeviceState> mDeviceStateMap GUARDED_BY(mLock);
        SimpleLog mSimpleLog GUARDED_BY(mLock) {64};
    } mSpatializer{*this};
Loading