/*
 *
 * Copyright 2023, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "AudioFlinger"
//#define LOG_NDEBUG 0
#include "AudioStreamIn.h"

#include <media/audiohal/DeviceHalInterface.h>
#include <media/audiohal/StreamHalInterface.h>
#include <system/audio.h>
#include <utils/Log.h>

#include "AudioHwDevice.h"

namespace android {

// ----------------------------------------------------------------------------
AudioStreamIn::AudioStreamIn(AudioHwDevice *dev, audio_input_flags_t flags)
        : audioHwDev(dev)
        , flags(flags)
{
}

// This must be defined here together with the HAL includes above and
// not solely in the header.
AudioStreamIn::~AudioStreamIn() = default;

sp<DeviceHalInterface> AudioStreamIn::hwDev() const
{
    return audioHwDev->hwDevice();
}

status_t AudioStreamIn::getCapturePosition(int64_t* frames, int64_t* time)
{
    if (stream == nullptr) {
        return NO_INIT;
    }

    int64_t halPosition = 0;
    const status_t status = stream->getCapturePosition(&halPosition, time);
    if (status != NO_ERROR) {
        return status;
    }

    if (mHalFormatHasProportionalFrames &&
            (flags & AUDIO_INPUT_FLAG_DIRECT) == AUDIO_INPUT_FLAG_DIRECT) {
        // For DirectRecord reset timestamp to 0 on standby.
        const uint64_t adjustedPosition = (halPosition <= mFramesReadAtStandby) ?
                0 : (halPosition - mFramesReadAtStandby);
        // Scale from HAL sample rate to application rate.
        *frames = adjustedPosition / mRateMultiplier;
    } else {
        // For compressed formats and linear PCM.
        *frames = halPosition;
    }

    return status;
}

status_t AudioStreamIn::open(
        audio_io_handle_t handle,
        audio_devices_t deviceType,
        struct audio_config *config,
        const char *address,
        audio_source_t source,
        audio_devices_t outputDevice,
        const char *outputDeviceAddress)
{
    sp<StreamInHalInterface> inStream;

    int status = hwDev()->openInputStream(
            handle,
            deviceType,
            config,
            flags,
            address,
            source,
            outputDevice,
            outputDeviceAddress,
            &inStream);
    ALOGV("AudioStreamIn::open(), HAL returned stream %p, sampleRate %d, format %#x,"
            " channelMask %#x, status %d", inStream.get(), config->sample_rate, config->format,
            config->channel_mask, status);

    if (status == NO_ERROR) {
        stream = inStream;
        mHalFormatHasProportionalFrames = audio_has_proportional_frames(config->format);
        status = stream->getFrameSize(&mHalFrameSize);
        LOG_ALWAYS_FATAL_IF(status != OK, "Error retrieving frame size from HAL: %d", status);
        LOG_ALWAYS_FATAL_IF(mHalFrameSize == 0, "Error frame size was %zu but must be greater than"
                " zero", mHalFrameSize);
    }

    return status;
}

audio_config_base_t AudioStreamIn::getAudioProperties() const
{
    audio_config_base_t result = AUDIO_CONFIG_BASE_INITIALIZER;
    if (stream->getAudioProperties(&result) != OK) {
        result.sample_rate = 0;
        result.channel_mask = AUDIO_CHANNEL_INVALID;
        result.format = AUDIO_FORMAT_INVALID;
    }
    return result;
}

status_t AudioStreamIn::standby()
{
    mFramesReadAtStandby = mFramesRead;
    return stream->standby();
}

status_t AudioStreamIn::read(void* buffer, size_t bytes, size_t* read)
{
    const status_t result = stream->read(buffer, bytes, read);
    if (result == OK && *read > 0 && mHalFrameSize > 0) {
        mFramesRead += *read / mHalFrameSize;
    }
    return result;
}

} // namespace android
