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

Commit 1c272c5c authored by Andy Hung's avatar Andy Hung Committed by Android (Google) Code Review
Browse files

Merge "MediaMetricsService: Extract common string utilities to audio_utils" into main

parents 55a32238 76a772a4
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -159,7 +159,7 @@ cc_library {
    },

    shared_libs: [
        "mediametricsservice-aidl-cpp",
        "libaudioutils",
        "libbase", // android logging
        "libbinder",
        "libcutils",
@@ -174,6 +174,7 @@ cc_library {
        "libstatspull",
        "libstatssocket",
        "libutils",
        "mediametricsservice-aidl-cpp",
        "packagemanager_aidl-cpp",
    ],

+2 −1
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <sstream>
#include <string>
#include <audio_utils/clock.h>
#include <audio_utils/StringUtils.h>
#include <cutils/properties.h>
#include <stats_media_metrics.h>
#include <sys/timerfd.h>
@@ -131,7 +132,7 @@ bool AudioPowerUsage::deviceFromString(const std::string& device_string, int32_t

int32_t AudioPowerUsage::deviceFromStringPairs(const std::string& device_strings) {
    int32_t deviceMask = 0;
    const auto devaddrvec = stringutils::getDeviceAddressPairs(device_strings);
    const auto devaddrvec = audio_utils::stringutils::getDeviceAddressPairs(device_strings);
    for (const auto &[device, addr] : devaddrvec) {
        int32_t combo_device = 0;
        deviceFromString(device, combo_device);
+7 −6
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include "AudioTypes.h"
#include "MediaMetricsConstants.h"
#include "StringUtils.h"
#include <audio_utils/StringUtils.h>
#include <media/TypeConverter.h> // requires libmedia_helper to get the Audio code.
#include <stats_media_metrics.h>            // statsd

@@ -349,7 +350,7 @@ const std::unordered_map<std::string, int32_t>& getStatusMap() {
template <typename Traits>
int32_t int32FromFlags(const std::string &flags)
{
    const auto result = stringutils::split(flags, "|");
    const auto result = audio_utils::stringutils::split(flags, "|");
    int32_t intFlags = 0;
    for (const auto& flag : result) {
        typename Traits::Type value;
@@ -364,7 +365,7 @@ int32_t int32FromFlags(const std::string &flags)
template <typename Traits>
std::string stringFromFlags(const std::string &flags, size_t len)
{
    const auto result = stringutils::split(flags, "|");
    const auto result = audio_utils::stringutils::split(flags, "|");
    std::string sFlags;
    for (const auto& flag : result) {
        typename Traits::Type value;
@@ -383,7 +384,7 @@ std::string validateStringFromMap(const std::string &str, const M& map)
{
    if (str.empty()) return {};

    const auto result = stringutils::split(str, "|");
    const auto result = audio_utils::stringutils::split(str, "|");
    std::stringstream ss;
    for (const auto &s : result) {
        if (map.count(s) > 0) {
@@ -399,7 +400,7 @@ typename M::mapped_type flagsFromMap(const std::string &str, const M& map)
{
    if (str.empty()) return {};

    const auto result = stringutils::split(str, "|");
    const auto result = audio_utils::stringutils::split(str, "|");
    typename M::mapped_type value{};
    for (const auto &s : result) {
        auto it = map.find(s);
@@ -416,7 +417,7 @@ std::vector<int32_t> vectorFromMap(

    if (str.empty()) return v;

    const auto result = stringutils::split(str, "|");
    const auto result = audio_utils::stringutils::split(str, "|");
    for (const auto &s : result) {
        auto it = map.find(s);
        if (it == map.end()) continue;
@@ -429,7 +430,7 @@ std::vector<int64_t> channelMaskVectorFromString(const std::string &s)
{
    std::vector<int64_t> v;

    const auto result = stringutils::split(s, "|");
    const auto result = audio_utils::stringutils::split(s, "|");
    for (const auto &mask : result) {
        // 0 if undetected or if actually 0.
        int64_t int64Mask = strtoll(mask.c_str(), nullptr, 0);
+3 −96
Original line number Diff line number Diff line
@@ -19,105 +19,12 @@
#include <utils/Log.h>

#include "StringUtils.h"

#include <charconv>

#include "AudioTypes.h"
#include <audio_utils/StringUtils.h>
#include <charconv>

namespace android::mediametrics::stringutils {

std::string tokenizer(std::string::const_iterator& it,
        const std::string::const_iterator& end, const char *reserved)
{
    // consume leading white space
    for (; it != end && std::isspace(*it); ++it);
    if (it == end) return {};

    auto start = it;
    // parse until we hit a reserved keyword or space
    if (strchr(reserved, *it)) return {start, ++it};
    for (;;) {
        ++it;
        if (it == end || std::isspace(*it) || strchr(reserved, *it)) return {start, it};
    }
}

std::vector<std::string> split(const std::string& flags, const char *delim)
{
    std::vector<std::string> result;
    for (auto it = flags.begin(); ; ) {
        auto flag = tokenizer(it, flags.end(), delim);
        if (flag.empty() || !std::isalnum(flag[0])) return result;
        result.emplace_back(std::move(flag));

        // look for the delimeter and discard
        auto token = tokenizer(it, flags.end(), delim);
        if (token.size() != 1 || strchr(delim, token[0]) == nullptr) return result;
    }
}

bool parseVector(const std::string &str, std::vector<int32_t> *vector) {
    std::vector<int32_t> values;
    const char *p = str.c_str();
    const char *last = p + str.size();
    while (p != last) {
        if (*p == ',' || *p == '{' || *p == '}') {
            p++;
        }
        int32_t value = -1;
        auto [ptr, error] = std::from_chars(p, last, value);
        if (error == std::errc::invalid_argument || error == std::errc::result_out_of_range) {
            return false;
        }
        p = ptr;
        values.push_back(value);
    }
    *vector = std::move(values);
    return true;
}

std::vector<std::pair<std::string, std::string>> getDeviceAddressPairs(const std::string& devices)
{
    std::vector<std::pair<std::string, std::string>> result;

    // Currently, the device format is
    //
    // devices = device_addr OR device_addr|devices
    // device_addr = device OR (device, addr)
    //
    // EXAMPLE:
    // device1|(device2, addr2)|...

    static constexpr char delim[] = "()|,";
    for (auto it = devices.begin(); ; ) {
        std::string address;
        std::string device = tokenizer(it, devices.end(), delim);
        if (device.empty()) return result;
        if (device == "(") {  // it is a pair otherwise we consider it a device
            device = tokenizer(it, devices.end(), delim); // get actual device
            auto token = tokenizer(it, devices.end(), delim);
            if (token != ",") return result;  // malformed, must have a comma

            // special handling here for empty addresses
            address = tokenizer(it, devices.end(), delim);
            if (address.empty()) return result;
            if (address == ")") {  // no address, just the ")"
                address.clear();
            } else {
                token = tokenizer(it, devices.end(), delim);
                if (token != ")") return result;
            }
        }
        // misaligned token, device must start alphanumeric.
        if (!std::isalnum(device[0])) return result;

        result.emplace_back(std::move(device), std::move(address));

        auto token = tokenizer(it, devices.end(), delim);
        if (token != "|") return result;  // this includes end of string detection
    }
}

size_t replace(std::string &str, const char *targetChars, const char replaceChar)
{
    size_t replaced = 0;
@@ -134,7 +41,7 @@ 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);
    const auto devaddrvec = audio_utils::stringutils::getDeviceAddressPairs(devicePairs);
    for (const auto& [device, addr] : devaddrvec) { // addr ignored for now.
        if (!result.second.empty()) {
            result.second.append("|"); // delimit devices with '|'.
+1 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ cc_defaults {
    ],

    shared_libs: [
        "libaudioutils",
        "libbase",
        "libbinder",
        "libcutils",
Loading