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

Commit 5a26d2fd authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 6134912 from 4793ecdd to rvc-release

Change-Id: I2ef86b99286390e7ee6e0e03e05b1c0661ac634d
parents ce17997f 4793ecdd
Loading
Loading
Loading
Loading
+7 −8
Original line number Diff line number Diff line
@@ -84,14 +84,13 @@ using android::Vector;
using android::sp;
using android::status_t;

using android::DISPLAY_ORIENTATION_0;
using android::DISPLAY_ORIENTATION_180;
using android::DISPLAY_ORIENTATION_90;
using android::INVALID_OPERATION;
using android::NAME_NOT_FOUND;
using android::NO_ERROR;
using android::UNKNOWN_ERROR;

namespace ui = android::ui;

static const uint32_t kMinBitRate = 100000;         // 0.1Mbps
static const uint32_t kMaxBitRate = 200 * 1000000;  // 200Mbps
static const uint32_t kMaxTimeLimitSec = 180;       // 3 minutes
@@ -328,7 +327,7 @@ static status_t setDisplayProjection(
    }

    t.setDisplayProjection(dpy,
            gRotate ? DISPLAY_ORIENTATION_90 : DISPLAY_ORIENTATION_0,
            gRotate ? ui::ROTATION_90 : ui::ROTATION_0,
            layerStackRect, displayRect);
    return NO_ERROR;
}
@@ -414,7 +413,7 @@ static status_t writeWinscopeMetadata(const Vector<int64_t>& timestamps,
 */
static status_t runEncoder(const sp<MediaCodec>& encoder,
        AMediaMuxer *muxer, FILE* rawFp, const sp<IBinder>& display,
        const sp<IBinder>& virtualDpy, uint8_t orientation) {
        const sp<IBinder>& virtualDpy, ui::Rotation orientation) {
    static int kTimeout = 250000;   // be responsive on signal
    status_t err;
    ssize_t trackIdx = -1;
@@ -484,7 +483,7 @@ static status_t runEncoder(const sp<MediaCodec>& encoder,
                    if (err != NO_ERROR) {
                        ALOGW("getDisplayInfo(main) failed: %d", err);
                    } else if (orientation != displayInfo.orientation) {
                        ALOGD("orientation changed, now %d", displayInfo.orientation);
                        ALOGD("orientation changed, now %s", toCString(displayInfo.orientation));
                        SurfaceComposerClient::Transaction t;
                        setDisplayProjection(t, virtualDpy, displayInfo);
                        t.apply();
@@ -691,9 +690,9 @@ static status_t recordScreen(const char* fileName) {
    }

    if (gVerbose) {
        printf("Display is %dx%d @%.2ffps (orientation=%u), layerStack=%u\n",
        printf("Display is %dx%d @%.2ffps (orientation=%s), layerStack=%u\n",
                displayInfo.viewportW, displayInfo.viewportH, displayInfo.fps,
                displayInfo.orientation, displayInfo.layerStack);
                toCString(displayInfo.orientation), displayInfo.layerStack);
        fflush(stdout);
    }

+43 −0
Original line number Diff line number Diff line
@@ -35,6 +35,49 @@

namespace android {

/*
 * MediaMetrics Keys and Properties for Audio.
 *
 * C/C++ friendly constants that ensure
 * 1) Compilation error on misspelling
 * 2) Consistent behavior and documentation.
 *
 * TODO: Move to separate header file.
 */

// Taxonomy of audio keys

// Key Prefixes are used for MediaMetrics Item Keys and ends with a ".".
// They must be appended with another value to make a key.
#define AMEDIAMETRICS_KEY_PREFIX_AUDIO "audio."

// The AudioRecord key appends the "trackId" to the prefix.
#define AMEDIAMETRICS_KEY_PREFIX_AUDIO_RECORD AMEDIAMETRICS_KEY_PREFIX_AUDIO "record."

// The AudioThread key appends the "threadId" to the prefix.
#define AMEDIAMETRICS_KEY_PREFIX_AUDIO_THREAD AMEDIAMETRICS_KEY_PREFIX_AUDIO "thread."

// The AudioTrack key appends the "trackId" to the prefix.
#define AMEDIAMETRICS_KEY_PREFIX_AUDIO_TRACK  AMEDIAMETRICS_KEY_PREFIX_AUDIO "track."

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

// Props are properties allowed for Mediametrics Items.
#define AMEDIAMETRICS_PROP_EVENT          "event"          // string value (often func name)
#define AMEDIAMETRICS_PROP_LATENCYMS      "latencyMs"      // double value
#define AMEDIAMETRICS_PROP_OUTPUTDEVICES  "outputDevices"  // string value
#define AMEDIAMETRICS_PROP_STARTUPMS      "startupMs"      // double value
#define AMEDIAMETRICS_PROP_THREADID       "threadId"       // int32 value io handle

// Values are strings accepted for a given property.

// An event is a general description, which often is a function name.
#define AMEDIAMETRICS_PROP_EVENT_VALUE_CTOR       "ctor"
#define AMEDIAMETRICS_PROP_EVENT_VALUE_DTOR       "dtor"
#define AMEDIAMETRICS_PROP_EVENT_VALUE_UNDERRUN   "underrun" // from Thread

class IMediaMetricsService;
class Parcel;

+1 −0
Original line number Diff line number Diff line
@@ -159,6 +159,7 @@ void Encoder::deInitCodec() {
        AMediaFormat_delete(mFormat);
        mFormat = nullptr;
    }
    if (!mCodec) return;
    AMediaCodec_stop(mCodec);
    AMediaCodec_delete(mCodec);
    int64_t eTime = mStats->getCurTime();
+18 −0
Original line number Diff line number Diff line
@@ -55,6 +55,24 @@ public:
        return mTimeMachine.put(item, isTrusted) ?: mTransactionLog.put(item);
    }

    /**
     * Returns the TimeMachine.
     *
     * The TimeMachine object is internally locked, so access is safe and defined,
     * but multiple threaded access may change results after calling.
     */
    TimeMachine& timeMachine() { return mTimeMachine; }
    const TimeMachine& timeMachine() const { return mTimeMachine; }

    /**
     * Returns the TransactionLog.
     *
     * The TransactionLog object is internally locked, so access is safe and defined,
     * but multiple threaded access may change results after calling.
     */
    TransactionLog& transactionLog() { return mTransactionLog; }
    const TransactionLog& transactionLog() const { return mTransactionLog; }

    /**
     * Returns a pair consisting of the dump string, and the number of lines in the string.
     *
+61 −5
Original line number Diff line number Diff line
@@ -32,16 +32,60 @@ AudioAnalytics::AudioAnalytics()
    // This triggers on an item of "audio.flinger"
    // with a property "event" set to "AudioFlinger" (the constructor).
    mActions.addAction(
        "audio.flinger.event",
        std::string("AudioFlinger"),
        AMEDIAMETRICS_KEY_AUDIO_FLINGER "." AMEDIAMETRICS_PROP_EVENT,
        std::string(AMEDIAMETRICS_PROP_EVENT_VALUE_CTOR),
        std::make_shared<AnalyticsActions::Function>(
            [this](const std::shared_ptr<const android::mediametrics::Item> &){
                ALOGW("Audioflinger() constructor event detected");
            [this](const std::shared_ptr<const android::mediametrics::Item> &item){
                ALOGW("(key=%s) Audioflinger constructor event detected", item->getKey().c_str());
                mPreviousAnalyticsState.set(std::make_shared<AnalyticsState>(
                        *mAnalyticsState.get()));
                // Note: get returns shared_ptr temp, whose lifetime is extended
                // to end of full expression.
                mAnalyticsState->clear();  // TODO: filter the analytics state.
                // Perhaps report this.
            }));

    // Check underruns
    mActions.addAction(
        AMEDIAMETRICS_KEY_PREFIX_AUDIO_THREAD "*." AMEDIAMETRICS_PROP_EVENT,
        std::string(AMEDIAMETRICS_PROP_EVENT_VALUE_UNDERRUN),
        std::make_shared<AnalyticsActions::Function>(
            [this](const std::shared_ptr<const android::mediametrics::Item> &item){
                std::string threadId = item->getKey().substr(
                        sizeof(AMEDIAMETRICS_KEY_PREFIX_AUDIO_THREAD) - 1);
                std::string outputDevices;
                mAnalyticsState->timeMachine().get(
                        item->getKey(), AMEDIAMETRICS_PROP_OUTPUTDEVICES, &outputDevices);
                ALOGD("(key=%s) Thread underrun event detected on io handle:%s device:%s",
                        item->getKey().c_str(), threadId.c_str(), outputDevices.c_str());
                if (outputDevices.find("AUDIO_DEVICE_OUT_BLUETOOTH") != std::string::npos) {
                    // report this for Bluetooth
                }
            }));

    // Check latencies, playback and startup
    mActions.addAction(
        AMEDIAMETRICS_KEY_PREFIX_AUDIO_TRACK "*." AMEDIAMETRICS_PROP_LATENCYMS,
        std::monostate{},  // accept any value
        std::make_shared<AnalyticsActions::Function>(
            [this](const std::shared_ptr<const android::mediametrics::Item> &item){
                double latencyMs{};
                double startupMs{};
                if (!item->get(AMEDIAMETRICS_PROP_LATENCYMS, &latencyMs)
                        || !item->get(AMEDIAMETRICS_PROP_STARTUPMS, &startupMs)) return;

                std::string trackId = item->getKey().substr(
                        sizeof(AMEDIAMETRICS_KEY_PREFIX_AUDIO_TRACK) - 1);
                std::string thread = getThreadFromTrack(item->getKey());
                std::string outputDevices;
                mAnalyticsState->timeMachine().get(
                        thread, AMEDIAMETRICS_PROP_OUTPUTDEVICES, &outputDevices);
                ALOGD("(key=%s) Track latencyMs:%lf startupMs:%lf detected on port:%s device:%s",
                        item->getKey().c_str(), latencyMs, startupMs,
                        trackId.c_str(), outputDevices.c_str());
                if (outputDevices.find("AUDIO_DEVICE_OUT_BLUETOOTH") != std::string::npos) {
                    // report this for Bluetooth
                }
            }));
}

@@ -53,7 +97,7 @@ AudioAnalytics::~AudioAnalytics()
status_t AudioAnalytics::submit(
        const std::shared_ptr<const mediametrics::Item>& item, bool isTrusted)
{
    if (!startsWith(item->getKey(), "audio.")) return BAD_VALUE;
    if (!startsWith(item->getKey(), AMEDIAMETRICS_KEY_PREFIX_AUDIO)) return BAD_VALUE;
    status_t status = mAnalyticsState->submit(item, isTrusted);
    if (status != NO_ERROR) return status;  // may not be permitted.

@@ -94,4 +138,16 @@ void AudioAnalytics::checkActions(const std::shared_ptr<const mediametrics::Item
    }
}

// HELPER METHODS

std::string AudioAnalytics::getThreadFromTrack(const std::string& track) const
{
    int32_t threadId_int32{};
    if (mAnalyticsState->timeMachine().get(
            track, AMEDIAMETRICS_PROP_THREADID, &threadId_int32) != NO_ERROR) {
        return {};
    }
    return std::string(AMEDIAMETRICS_KEY_PREFIX_AUDIO_THREAD) + std::to_string(threadId_int32);
}

} // namespace android
Loading