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

Commit 0825031e authored by Eric Laurent's avatar Eric Laurent Committed by Andy Hung
Browse files

AudioSystem: add APIs to control HAL stream latency mode

Add API to AudioSystem and AudioFlinger to discover and control
the latency modes supported by audio HAL streams

Bug: 218273231
Test: make
Merged-In: I84c2325301cc7a4cf058fa076d0645ede877b54f
Change-Id: I84c2325301cc7a4cf058fa076d0645ede877b54f
parent b22c6b25
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -3388,4 +3388,24 @@ ConversionResult<int32_t> legacy2aidl_audio_direct_mode_t_int32_t_mask(audio_dir
            enumToMask_index<int32_t, media::AudioDirectMode>);
}

ConversionResult<audio_latency_mode_t>
aidl2legacy_LatencyMode_audio_latency_mode_t(media::LatencyMode aidl) {
    switch (aidl) {
        case media::LatencyMode::FREE:
            return AUDIO_LATENCY_MODE_FREE;
        case media::LatencyMode::LOW:
            return AUDIO_LATENCY_MODE_LOW;
    }
    return unexpected(BAD_VALUE);
}
ConversionResult<media::LatencyMode>
legacy2aidl_audio_latency_mode_t_LatencyMode(audio_latency_mode_t legacy) {
    switch (legacy) {
        case AUDIO_LATENCY_MODE_FREE:
            return media::LatencyMode::FREE;
        case AUDIO_LATENCY_MODE_LOW:
            return media::LatencyMode::LOW;
    }
    return unexpected(BAD_VALUE);
}
}  // namespace android
+1 −0
Original line number Diff line number Diff line
@@ -356,6 +356,7 @@ aidl_interface {
        "aidl/android/media/AudioUniqueIdUse.aidl",
        "aidl/android/media/AudioVibratorInfo.aidl",
        "aidl/android/media/EffectDescriptor.aidl",
        "aidl/android/media/LatencyMode.aidl",
        "aidl/android/media/TrackSecondaryOutputInfo.aidl",
    ],
    imports: [
+85 −0
Original line number Diff line number Diff line
@@ -670,6 +670,30 @@ Status AudioSystem::AudioFlingerClient::ioConfigChanged(
    return Status::ok();
}

Status AudioSystem::AudioFlingerClient::onSupportedLatencyModesChanged(
        int output, const std::vector<media::LatencyMode>& latencyModes) {
    audio_io_handle_t outputLegacy = VALUE_OR_RETURN_BINDER_STATUS(
            aidl2legacy_int32_t_audio_io_handle_t(output));
    std::vector<audio_latency_mode_t> modesLegacy = VALUE_OR_RETURN_BINDER_STATUS(
            convertContainer<std::vector<audio_latency_mode_t>>(
                    latencyModes, aidl2legacy_LatencyMode_audio_latency_mode_t));

    std::vector<sp<SupportedLatencyModesCallback>> callbacks;
    {
        Mutex::Autolock _l(mLock);
        for (auto callback : mSupportedLatencyModesCallbacks) {
            if (auto ref = callback.promote(); ref != nullptr) {
                callbacks.push_back(ref);
            }
        }
    }
    for (const auto& callback : callbacks) {
        callback->onSupportedLatencyModesChanged(outputLegacy, modesLegacy);
    }

    return Status::ok();
}

status_t AudioSystem::AudioFlingerClient::getInputBufferSize(
        uint32_t sampleRate, audio_format_t format,
        audio_channel_mask_t channelMask, size_t* buffSize) {
@@ -749,6 +773,31 @@ status_t AudioSystem::AudioFlingerClient::removeAudioDeviceCallback(
    return NO_ERROR;
}

status_t AudioSystem::AudioFlingerClient::addSupportedLatencyModesCallback(
        const sp<SupportedLatencyModesCallback>& callback) {
    Mutex::Autolock _l(mLock);
    if (std::find(mSupportedLatencyModesCallbacks.begin(),
                  mSupportedLatencyModesCallbacks.end(),
                  callback) != mSupportedLatencyModesCallbacks.end()) {
        return INVALID_OPERATION;
    }
    mSupportedLatencyModesCallbacks.push_back(callback);
    return NO_ERROR;
}

status_t AudioSystem::AudioFlingerClient::removeSupportedLatencyModesCallback(
        const sp<SupportedLatencyModesCallback>& callback) {
    Mutex::Autolock _l(mLock);
    auto it = std::find(mSupportedLatencyModesCallbacks.begin(),
                                 mSupportedLatencyModesCallbacks.end(),
                                 callback);
    if (it == mSupportedLatencyModesCallbacks.end()) {
        return INVALID_OPERATION;
    }
    mSupportedLatencyModesCallbacks.erase(it);
    return NO_ERROR;
}

/* static */ uintptr_t AudioSystem::addErrorCallback(audio_error_callback cb) {
    Mutex::Autolock _l(gLockErrorCallbacks);
    gAudioErrorCallbacks.insert(cb);
@@ -1662,6 +1711,24 @@ status_t AudioSystem::removeAudioDeviceCallback(
    return afc->removeAudioDeviceCallback(callback, audioIo, portId);
}

status_t AudioSystem::addSupportedLatencyModesCallback(
        const sp<SupportedLatencyModesCallback>& callback) {
    const sp<AudioFlingerClient> afc = getAudioFlingerClient();
    if (afc == 0) {
        return NO_INIT;
    }
    return afc->addSupportedLatencyModesCallback(callback);
}

status_t AudioSystem::removeSupportedLatencyModesCallback(
        const sp<SupportedLatencyModesCallback>& callback) {
    const sp<AudioFlingerClient> afc = getAudioFlingerClient();
    if (afc == 0) {
        return NO_INIT;
    }
    return afc->removeSupportedLatencyModesCallback(callback);
}

audio_port_handle_t AudioSystem::getDeviceIdForIo(audio_io_handle_t audioIo) {
    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
    if (af == 0) return PERMISSION_DENIED;
@@ -2341,6 +2408,24 @@ status_t AudioSystem::getDirectProfilesForAttributes(const audio_attributes_t* a
    return NO_ERROR;
}

status_t AudioSystem::setRequestedLatencyMode(
            audio_io_handle_t output, audio_latency_mode_t mode) {
    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
    if (af == nullptr) {
        return PERMISSION_DENIED;
    }
    return af->setRequestedLatencyMode(output, mode);
}

status_t AudioSystem::getSupportedLatencyModes(audio_io_handle_t output,
        std::vector<audio_latency_mode_t>* modes) {
    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
    if (af == nullptr) {
        return PERMISSION_DENIED;
    }
    return af->getSupportedLatencyModes(output, modes);
}

class CaptureStateListenerImpl : public media::BnCaptureStateListener,
                                 public IBinder::DeathRecipient {
public:
+51 −0
Original line number Diff line number Diff line
@@ -810,6 +810,33 @@ status_t AudioFlingerClientAdapter::setDeviceConnectedState(
    return statusTFromBinderStatus(mDelegate->setDeviceConnectedState(aidlPort, connected));
}

status_t AudioFlingerClientAdapter::setRequestedLatencyMode(
        audio_io_handle_t output, audio_latency_mode_t mode) {
    int32_t outputAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(output));
    media::LatencyMode modeAidl  = VALUE_OR_RETURN_STATUS(
            legacy2aidl_audio_latency_mode_t_LatencyMode(mode));
    return statusTFromBinderStatus(mDelegate->setRequestedLatencyMode(outputAidl, modeAidl));
}

status_t AudioFlingerClientAdapter::getSupportedLatencyModes(
        audio_io_handle_t output, std::vector<audio_latency_mode_t>* modes) {
    if (modes == nullptr) {
        return BAD_VALUE;
    }

    int32_t outputAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(output));
    std::vector<media::LatencyMode> modesAidl;

    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
            mDelegate->getSupportedLatencyModes(outputAidl, &modesAidl)));

    *modes = VALUE_OR_RETURN_STATUS(
            convertContainer<std::vector<audio_latency_mode_t>>(modesAidl,
                     aidl2legacy_LatencyMode_audio_latency_mode_t));

    return NO_ERROR;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// AudioFlingerServerAdapter
AudioFlingerServerAdapter::AudioFlingerServerAdapter(
@@ -1304,4 +1331,28 @@ Status AudioFlingerServerAdapter::setDeviceConnectedState(
    return Status::fromStatusT(mDelegate->setDeviceConnectedState(&portLegacy, connected));
}

Status AudioFlingerServerAdapter::setRequestedLatencyMode(
        int32_t output, media::LatencyMode modeAidl) {
    audio_io_handle_t outputLegacy = VALUE_OR_RETURN_BINDER(
            aidl2legacy_int32_t_audio_io_handle_t(output));
    audio_latency_mode_t modeLegacy = VALUE_OR_RETURN_BINDER(
            aidl2legacy_LatencyMode_audio_latency_mode_t(modeAidl));
    return Status::fromStatusT(mDelegate->setRequestedLatencyMode(
            outputLegacy, modeLegacy));
}

Status AudioFlingerServerAdapter::getSupportedLatencyModes(
        int output, std::vector<media::LatencyMode>* _aidl_return) {
    audio_io_handle_t outputLegacy = VALUE_OR_RETURN_BINDER(
            aidl2legacy_int32_t_audio_io_handle_t(output));
    std::vector<audio_latency_mode_t> modesLegacy;

    RETURN_BINDER_IF_ERROR(mDelegate->getSupportedLatencyModes(outputLegacy, &modesLegacy));

    *_aidl_return = VALUE_OR_RETURN_BINDER(
            convertContainer<std::vector<media::LatencyMode>>(
                    modesLegacy, legacy2aidl_audio_latency_mode_t_LatencyMode));
    return Status::ok();
}

} // namespace android
+7 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.media;

import android.media.AudioIoConfigEvent;
import android.media.AudioIoDescriptor;
import android.media.LatencyMode;

/**
 * A callback interface for AudioFlinger.
@@ -27,4 +28,10 @@ import android.media.AudioIoDescriptor;
interface IAudioFlingerClient {
    oneway void ioConfigChanged(AudioIoConfigEvent event,
                                in AudioIoDescriptor ioDesc);
    /**
     * Called when the latency modes supported on a given output stream change.
     * output is the I/O handle of the output stream for which the change is signalled.
     * latencyModes is the new list of supported latency modes (See LatencyMode.aidl).
     */
    oneway void onSupportedLatencyModesChanged(int output, in LatencyMode[] latencyModes);
}
Loading