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

Commit 93845c24 authored by Mikhail Naganov's avatar Mikhail Naganov
Browse files

libaudiohal@aidl: Fix handling of "unknown" position

In HIDL HAL, methods for returning the current position could
return 'ENOSYS' indicating that it can't be currently retrieved.
The AIDL HAL adapter was missing this behavior. Instead, it
was clamping the returned 'UNKNOWN' position to '0', causing
issues with frame accounting at the framework layer.

Bug: 374929507
Test: atest audiorecord_tests audioeffect_tests audiorouting_tests
Test: atest trackplayerbase_tests audiosystem_tests
Test: atest CtsMediaAudioTestCases
Change-Id: I24faa2fb4075ee0c5762a8780a5f6cb94697d961
parent a10a2f5c
Loading
Loading
Loading
Loading
+21 −7
Original line number Diff line number Diff line
@@ -367,8 +367,12 @@ status_t StreamHalAidl::getObservablePosition(int64_t* frames, int64_t* timestam
    if (!mStream) return NO_INIT;
    StreamDescriptor::Reply reply;
    RETURN_STATUS_IF_ERROR(updateCountersIfNeeded(&reply, statePositions));
    *frames = std::max<int64_t>(0, reply.observable.frames);
    *timestamp = std::max<int64_t>(0, reply.observable.timeNs);
    if (reply.observable.frames == StreamDescriptor::Position::UNKNOWN ||
        reply.observable.timeNs == StreamDescriptor::Position::UNKNOWN) {
        return INVALID_OPERATION;
    }
    *frames = reply.observable.frames;
    *timestamp = reply.observable.timeNs;
    return OK;
}

@@ -377,8 +381,12 @@ status_t StreamHalAidl::getHardwarePosition(int64_t *frames, int64_t *timestamp)
    if (!mStream) return NO_INIT;
    StreamDescriptor::Reply reply;
    RETURN_STATUS_IF_ERROR(updateCountersIfNeeded(&reply));
    *frames = std::max<int64_t>(0, reply.hardware.frames);
    *timestamp = std::max<int64_t>(0, reply.hardware.timeNs);
    if (reply.hardware.frames == StreamDescriptor::Position::UNKNOWN ||
        reply.hardware.timeNs == StreamDescriptor::Position::UNKNOWN) {
        return INVALID_OPERATION;
    }
    *frames = reply.hardware.frames;
    *timestamp = reply.hardware.timeNs;
    return OK;
}

@@ -387,7 +395,10 @@ status_t StreamHalAidl::getXruns(int32_t *frames) {
    if (!mStream) return NO_INIT;
    StreamDescriptor::Reply reply;
    RETURN_STATUS_IF_ERROR(updateCountersIfNeeded(&reply));
    *frames = std::max<int32_t>(0, reply.xrunFrames);
    if (reply.xrunFrames == StreamDescriptor::Position::UNKNOWN) {
        return INVALID_OPERATION;
    }
    *frames = reply.xrunFrames;
    return OK;
}

@@ -577,7 +588,9 @@ void StreamHalAidl::onAsyncDrainReady() {
        // For compatibility with HIDL behavior, apply a "soft" position reset
        // after receiving the "drain ready" callback.
        std::lock_guard l(mLock);
        if (mLastReply.observable.frames != StreamDescriptor::Position::UNKNOWN) {
            mStatePositions.framesAtFlushOrDrain = mLastReply.observable.frames;
        }
    } else {
        AUGMENT_LOG(W, "unexpected onDrainReady in the state %s", toString(state).c_str());
    }
@@ -670,7 +683,8 @@ status_t StreamHalAidl::sendCommand(
            }
            mLastReply = *reply;
            mLastReplyExpirationNs = uptimeNanos() + mLastReplyLifeTimeNs;
            if (!mIsInput && reply->status == STATUS_OK) {
            if (!mIsInput && reply->status == STATUS_OK &&
                    reply->observable.frames != StreamDescriptor::Position::UNKNOWN) {
                if (command.getTag() == StreamDescriptor::Command::standby &&
                        reply->state == StreamDescriptor::State::STANDBY) {
                    mStatePositions.framesAtStandby = reply->observable.frames;