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

Commit 9587d07c authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 8310722 from 424847d6 to tm-release

Change-Id: I80727f57b1a62f2c28171462545851f9d339e02d
parents 2362827f 424847d6
Loading
Loading
Loading
Loading
+1 −10
Original line number Diff line number Diff line
{
  "presubmit": [
    {
      "name": "CtsMediaDrmTestCases",
      "name": "CtsMediaDrmFrameworkTestCases",
      "options" : [
        {
          "include-annotation": "android.platform.test.annotations.Presubmit"
        },
        {
          "include-filter": "android.mediadrm.cts.MediaDrmClearkeyTest"
        },
        {
          "include-filter": "android.mediadrm.cts.MediaDrmMetricsTest"
        },
        {
          "include-filter": "android.mediadrm.cts.NativeMediaDrmClearkeyTest"
        }
      ]
    }
+2 −23
Original line number Diff line number Diff line
@@ -96,29 +96,8 @@ aaudio_result_t AudioStreamRecord::open(const AudioStreamBuilder& builder)
        setFormat(AUDIO_FORMAT_PCM_FLOAT);
    }

    // Maybe change device format to get a FAST path.
    // AudioRecord does not support FAST mode for FLOAT data.
    // TODO AudioRecord should allow FLOAT data paths for FAST tracks.
    // So IF the user asks for low latency FLOAT
    // AND the sampleRate is likely to be compatible with FAST
    // THEN request I16 and convert to FLOAT when passing to user.
    // Note that hard coding 48000 Hz is not ideal because the sampleRate
    // for a FAST path might not be 48000 Hz.
    // It normally is but there is a chance that it is not.
    // And there is no reliable way to know that in advance.
    // Luckily the consequences of a wrong guess are minor.
    // We just may not get a FAST track.
    // But we wouldn't have anyway without this hack.
    constexpr int32_t kMostLikelySampleRateForFast = 48000;
    if (getFormat() == AUDIO_FORMAT_PCM_FLOAT
            && perfMode == AAUDIO_PERFORMANCE_MODE_LOW_LATENCY
            && (audio_channel_count_from_in_mask(channelMask) <= 2) // FAST only for mono and stereo
            && (getSampleRate() == kMostLikelySampleRateForFast
                || getSampleRate() == AAUDIO_UNSPECIFIED)) {
        setDeviceFormat(AUDIO_FORMAT_PCM_16_BIT);
    } else {

    setDeviceFormat(getFormat());
    }

    // To avoid glitching, let AudioFlinger pick the optimal burst size.
    uint32_t notificationFrames = 0;
+5 −4
Original line number Diff line number Diff line
@@ -2151,7 +2151,7 @@ static void mapFormat(AString componentName, const sp<AMessage> &format, const c
                      bool reverse) {
    AString mediaType;
    if (!format->findString("mime", &mediaType)) {
        ALOGW("mapFormat: no mediaType information");
        ALOGV("mapFormat: no mediaType information");
        return;
    }
    ALOGV("mapFormat: codec %s mediatype %s kind %s reverse %d", componentName.c_str(),
@@ -3105,10 +3105,8 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
                        case STOPPING:
                        {
                            if (mFlags & kFlagSawMediaServerDie) {
                                bool postPendingReplies = true;
                                if (mState == RELEASING && !mReplyID) {
                                    ALOGD("Releasing asynchronously, so nothing to reply here.");
                                    postPendingReplies = false;
                                }
                                // MediaServer died, there definitely won't
                                // be a shutdown complete notification after
@@ -3121,8 +3119,11 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
                                if (mState == RELEASING) {
                                    mComponentName.clear();
                                }
                                if (postPendingReplies) {
                                if (mReplyID) {
                                    postPendingRepliesAndDeferredMessages(origin + ":dead");
                                } else {
                                    ALOGD("no pending replies: %s:dead following %s",
                                          origin.c_str(), mLastReplyOrigin.c_str());
                                }
                                sendErrorResponse = false;
                            } else if (!mReplyID) {
+48 −0
Original line number Diff line number Diff line
@@ -393,3 +393,51 @@ TEST(MediaCodecTest, DeadWhileAsyncReleasing) {
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    looper->stop();
}

TEST(MediaCodecTest, DeadWhileStoppingError) {
    // Test scenario:
    //
    // 1) Client thread calls stop(); MediaCodec looper thread calls
    //    initiateShutdown(); shutdown is being handled at the component thread.
    // 2) An error occurs while handling initiateShutdown().
    // 3) MediaCodec looper thread handles the error.
    // 4) Codec service dies after the error is handled
    // 5) MediaCodec looper thread handles the death.

    static const AString kCodecName{"test.codec"};
    static const AString kCodecOwner{"nobody"};
    static const AString kMediaType{"video/x-test"};

    sp<MockCodec> mockCodec;
    std::function<sp<CodecBase>(const AString &name, const char *owner)> getCodecBase =
        [&mockCodec](const AString &, const char *) {
            mockCodec = new MockCodec([](const std::shared_ptr<MockBufferChannel> &) {
                // No mock setup, as we don't expect any buffer operations
                // in this scenario.
            });
            ON_CALL(*mockCodec, initiateAllocateComponent(_))
                .WillByDefault([mockCodec](const sp<AMessage> &) {
                    mockCodec->callback()->onComponentAllocated(kCodecName.c_str());
                });
            ON_CALL(*mockCodec, initiateShutdown(_))
                .WillByDefault([mockCodec](bool) {
                    // 2)
                    mockCodec->callback()->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
                    // 4)
                    mockCodec->callback()->onError(DEAD_OBJECT, ACTION_CODE_FATAL);
                    // Codec service has died, no callback.
                });
            return mockCodec;
        };

    sp<ALooper> looper{new ALooper};
    sp<MediaCodec> codec = SetupMediaCodec(
            kCodecOwner, kCodecName, kMediaType, looper, getCodecBase);
    ASSERT_NE(nullptr, codec) << "Codec must not be null";
    ASSERT_NE(nullptr, mockCodec) << "MockCodec must not be null";

    codec->stop();
    // sleep here so that the looper thread can handle the error
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    looper->stop();
}
+2 −0
Original line number Diff line number Diff line
@@ -438,6 +438,8 @@ public:

    uint32_t getRecommendedMuteDurationMs() const override;

    void setTracksInvalidatedStatusByStrategy(product_strategy_t strategy);

    const sp<IOProfile> mProfile;          // I/O profile this output derives from
    audio_io_handle_t mIoHandle;           // output handle
    uint32_t mLatency;                  //
Loading