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

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

Merge "MIDI Metrics: Send MIDI Metrics to statsd"

parents 97c01d69 38439733
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -72,6 +72,7 @@

// Keys are strings used for MediaMetrics Item Keys
#define AMEDIAMETRICS_KEY_AUDIO_FLINGER       AMEDIAMETRICS_KEY_PREFIX_AUDIO "flinger"
#define AMEDIAMETRICS_KEY_AUDIO_MIDI          AMEDIAMETRICS_KEY_PREFIX_AUDIO "midi"
#define AMEDIAMETRICS_KEY_AUDIO_POLICY        AMEDIAMETRICS_KEY_PREFIX_AUDIO "policy"

// Error keys
@@ -124,9 +125,13 @@
#define AMEDIAMETRICS_PROP_CHANNELMASK    "channelMask"    // int32
#define AMEDIAMETRICS_PROP_CHANNELMASKS   "channelMasks"   // string with channelMask values
                                                           // separated by |.
#define AMEDIAMETRICS_PROP_CLOSEDCOUNT   "closedCount"    // int32 (MIDI)
#define AMEDIAMETRICS_PROP_CONTENTTYPE    "contentType"    // string attributes (AudioTrack)
#define AMEDIAMETRICS_PROP_CUMULATIVETIMENS "cumulativeTimeNs" // int64_t playback/record time
                                                           // since start
#define AMEDIAMETRICS_PROP_DEVICEDISCONNECTED "deviceDisconnected" // string true/false (MIDI)
#define AMEDIAMETRICS_PROP_DEVICEID       "deviceId"       // int32 device id (MIDI)

// DEVICE values are averaged since starting on device
#define AMEDIAMETRICS_PROP_DEVICELATENCYMS "deviceLatencyMs" // double - avg latency time
#define AMEDIAMETRICS_PROP_DEVICESTARTUPMS "deviceStartupMs" // double - avg startup time
@@ -150,12 +155,15 @@
#define AMEDIAMETRICS_PROP_FLAGS          "flags"

#define AMEDIAMETRICS_PROP_FRAMECOUNT     "frameCount"     // int32
#define AMEDIAMETRICS_PROP_HARDWARETYPE   "hardwareType"   // int32 (MIDI)
#define AMEDIAMETRICS_PROP_HASHEADTRACKER  "hasHeadTracker" // string true/false
#define AMEDIAMETRICS_PROP_HEADTRACKERENABLED "headTrackerEnabled" // string true/false
#define AMEDIAMETRICS_PROP_HEADTRACKINGMODES "headTrackingModes" // string |, like modes.
#define AMEDIAMETRICS_PROP_INPUTDEVICES   "inputDevices"   // string value
#define AMEDIAMETRICS_PROP_INPUTPORTCOUNT  "inputPortCount" // int32 (MIDI)
#define AMEDIAMETRICS_PROP_INTERNALTRACKID "internalTrackId" // int32
#define AMEDIAMETRICS_PROP_INTERVALCOUNT  "intervalCount"  // int32
#define AMEDIAMETRICS_PROP_ISSHARED      "isShared"       // string true/false (MIDI)
#define AMEDIAMETRICS_PROP_LATENCYMS      "latencyMs"      // double value
#define AMEDIAMETRICS_PROP_LEVELS         "levels"          // string | with levels
#define AMEDIAMETRICS_PROP_LOGSESSIONID   "logSessionId"   // hex string, "" none
@@ -165,7 +173,9 @@
#define AMEDIAMETRICS_PROP_MODES          "modes"          // string | with modes
#define AMEDIAMETRICS_PROP_NAME           "name"           // string value
#define AMEDIAMETRICS_PROP_ORIGINALFLAGS  "originalFlags"  // int32
#define AMEDIAMETRICS_PROP_OPENEDCOUNT   "openedCount"    // int32 (MIDI)
#define AMEDIAMETRICS_PROP_OUTPUTDEVICES  "outputDevices"  // string value
#define AMEDIAMETRICS_PROP_OUTPUTPORTCOUNT "outputPortCount" // int32 (MIDI)
#define AMEDIAMETRICS_PROP_PERFORMANCEMODE "performanceMode"    // string value, "none", lowLatency"
#define AMEDIAMETRICS_PROP_PLAYBACK_PITCH "playback.pitch" // double value (AudioTrack)
#define AMEDIAMETRICS_PROP_PLAYBACK_SPEED "playback.speed" // double value (AudioTrack)
@@ -194,6 +204,13 @@
                                                           // Treated as "debug" information.

#define AMEDIAMETRICS_PROP_STREAMTYPE     "streamType"     // string (AudioTrack)
#define AMEDIAMETRICS_PROP_SUPPORTSMIDIUMP "supportsMidiUmp" // string true/false (MIDI).
                                                             // Universal MIDI Packets is a new
                                                             // format to transport packets.
                                                             // Raw byte streams are used if this
                                                             // is false.
#define AMEDIAMETRICS_PROP_TOTALINPUTBYTES "totalInputBytes" // int32 (MIDI)
#define AMEDIAMETRICS_PROP_TOTALOUTPUTBYTES "totalOutputBytes" // int32 (MIDI)
#define AMEDIAMETRICS_PROP_THREADID       "threadId"       // int32 value io handle
#define AMEDIAMETRICS_PROP_THROTTLEMS     "throttleMs"     // double
#define AMEDIAMETRICS_PROP_TRACKID        "trackId"        // int32 port id of track/record
@@ -202,6 +219,7 @@
#define AMEDIAMETRICS_PROP_UNDERRUN       "underrun"       // int32
#define AMEDIAMETRICS_PROP_UNDERRUNFRAMES "underrunFrames" // int64_t from Thread
#define AMEDIAMETRICS_PROP_USAGE          "usage"          // string attributes (ATrack)
#define AMEDIAMETRICS_PROP_USINGALSA     "usingAlsa"      // string true/false (MIDI)
#define AMEDIAMETRICS_PROP_VOICEVOLUME    "voiceVolume"    // double (audio.flinger)
#define AMEDIAMETRICS_PROP_VOLUME_LEFT    "volume.left"    // double (AudioTrack)
#define AMEDIAMETRICS_PROP_VOLUME_RIGHT   "volume.right"   // double (AudioTrack)
@@ -226,6 +244,7 @@
#define AMEDIAMETRICS_PROP_EVENT_VALUE_CREATE     "create"
#define AMEDIAMETRICS_PROP_EVENT_VALUE_CREATEAUDIOPATCH "createAudioPatch"
#define AMEDIAMETRICS_PROP_EVENT_VALUE_CTOR       "ctor"
#define AMEDIAMETRICS_PROP_EVENT_VALUE_DEVICECLOSED "deviceClosed" // MIDI
#define AMEDIAMETRICS_PROP_EVENT_VALUE_DISCONNECT "disconnect"
#define AMEDIAMETRICS_PROP_EVENT_VALUE_DTOR       "dtor"
#define AMEDIAMETRICS_PROP_EVENT_VALUE_ENDAAUDIOSTREAM "endAAudioStream" // AAudioStream
+148 −0
Original line number Diff line number Diff line
@@ -269,6 +269,24 @@ static constexpr const char * SpatializerDeviceEnabledFields[] {
    "enabled",
};

static constexpr const char * const MidiDeviceCloseFields[] {
    "mediametrics_midi_device_close_reported",
    "uid",
    "midi_device_id",
    "input_port_count",
    "output_port_count",
    "device_type",
    "is_shared",
    "supports_ump",
    "using_alsa",
    "duration_ns",
    "opened_count",
    "closed_count",
    "device_disconnected",
    "total_input_bytes",
    "total_output_bytes",
};

/**
 * printFields is a helper method that prints the fields and corresponding values
 * in a human readable style.
@@ -497,6 +515,15 @@ AudioAnalytics::AudioAnalytics(const std::shared_ptr<StatsdLog>& statsdLog)
            [this](const std::shared_ptr<const android::mediametrics::Item> &item){
                mSpatializer.onEvent(item);
            }));

    // Handle MIDI
    mActions.addAction(
        AMEDIAMETRICS_KEY_AUDIO_MIDI "." AMEDIAMETRICS_PROP_EVENT,
        std::string(AMEDIAMETRICS_PROP_EVENT_VALUE_DEVICECLOSED),
        std::make_shared<AnalyticsActions::Function>(
            [this](const std::shared_ptr<const android::mediametrics::Item> &item) {
                mMidiLogging.onEvent(item);
            }));
}

AudioAnalytics::~AudioAnalytics()
@@ -1710,6 +1737,127 @@ std::pair<std::string, int32_t> AudioAnalytics::Spatializer::dump(
    return { s, n };
}

void AudioAnalytics::MidiLogging::onEvent(
        const std::shared_ptr<const android::mediametrics::Item> &item) const {
    const std::string& key = item->getKey();

    const auto uid = item->getUid();

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

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

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

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

    std::string isSharedString;
    mAudioAnalytics.mAnalyticsState->timeMachine().get(
            key, AMEDIAMETRICS_PROP_ISSHARED, &isSharedString);
    const bool isShared = (isSharedString == "true");

    std::string supportsMidiUmpString;
    mAudioAnalytics.mAnalyticsState->timeMachine().get(
            key, AMEDIAMETRICS_PROP_SUPPORTSMIDIUMP, &supportsMidiUmpString);
    const bool supportsMidiUmp = (supportsMidiUmpString == "true");

    std::string usingAlsaString;
    mAudioAnalytics.mAnalyticsState->timeMachine().get(
            key, AMEDIAMETRICS_PROP_USINGALSA, &usingAlsaString);
    const bool usingAlsa = (usingAlsaString == "true");

    int64_t durationNs = -1;
    mAudioAnalytics.mAnalyticsState->timeMachine().get(
            key, AMEDIAMETRICS_PROP_DURATIONNS, &durationNs);

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

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

    std::string deviceDisconnectedString;
    mAudioAnalytics.mAnalyticsState->timeMachine().get(
            key, AMEDIAMETRICS_PROP_DEVICEDISCONNECTED, &deviceDisconnectedString);
    const bool deviceDisconnected = (deviceDisconnectedString == "true");

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

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

    LOG(LOG_LEVEL) << "key:" << key
            << " uid:" << uid
            << " id:" << deviceId
            << " input_port_count:" << inputPortCount
            << " output_port_count:" << outputPortCount
            << " device_type:" << hardwareType
            << " is_shared:" << isSharedString
            << " supports_ump:" << supportsMidiUmpString
            << " using_alsa:" << usingAlsaString
            << " duration_opened_ms:" << durationNs
            << " opened_count:" << openedCount
            << " closed_count:" << closedCount
            << " device_disconnected:" << deviceDisconnectedString
            << " total_input_bytes:" << totalInputBytes
            << " total_output_bytes:" << totalOutputBytes;

    if (mAudioAnalytics.mDeliverStatistics) {
        const auto result = sendToStatsd(
                CONDITION(stats::media_metrics::MEDIAMETRICS_MIDI_DEVICE_CLOSE_REPORTED)
                , uid
                , deviceId
                , inputPortCount
                , outputPortCount
                , hardwareType
                , isShared
                , supportsMidiUmp
                , usingAlsa
                , durationNs
                , openedCount
                , closedCount
                , deviceDisconnected
                , totalInputBytes
                , totalOutputBytes);
        std::stringstream ss;
        ss << "result:" << result;
        const auto fieldsStr = printFields(MidiDeviceCloseFields,
                CONDITION(stats::media_metrics::MEDIAMETRICS_MIDI_DEVICE_CLOSE_REPORTED)
                , uid
                , deviceId
                , inputPortCount
                , outputPortCount
                , hardwareType
                , isShared
                , supportsMidiUmp
                , usingAlsa
                , durationNs
                , openedCount
                , closedCount
                , deviceDisconnected
                , totalInputBytes
                , totalOutputBytes);
        ss << " " << fieldsStr;
        std::string str = ss.str();
        ALOGV("%s: statsd %s", __func__, str.c_str());
        mAudioAnalytics.mStatsdLog->log(
                stats::media_metrics::MEDIAMETRICS_MIDI_DEVICE_CLOSE_REPORTED, str);
    }
}

// This method currently suppresses the name.
std::string AudioAnalytics::getDeviceNamesFromOutputDevices(std::string_view devices) const {
    std::string deviceNames;
+14 −0
Original line number Diff line number Diff line
@@ -363,6 +363,20 @@ private:
        SimpleLog mSimpleLog GUARDED_BY(mLock) {64};
    } mSpatializer{*this};

    // MidiLogging collects info whenever a MIDI device is closed.
    class MidiLogging {
    public:
        explicit MidiLogging(AudioAnalytics &audioAnalytics)
            : mAudioAnalytics(audioAnalytics) {}

        void onEvent(
                const std::shared_ptr<const android::mediametrics::Item> &item) const;

    private:

        AudioAnalytics &mAudioAnalytics;
    } mMidiLogging{*this};

    AudioPowerUsage mAudioPowerUsage;
};