150a07fd2Sopenharmony_ci/*
250a07fd2Sopenharmony_ci * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
350a07fd2Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
450a07fd2Sopenharmony_ci * you may not use this file except in compliance with the License.
550a07fd2Sopenharmony_ci * You may obtain a copy of the License at
650a07fd2Sopenharmony_ci *
750a07fd2Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
850a07fd2Sopenharmony_ci *
950a07fd2Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1050a07fd2Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1150a07fd2Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1250a07fd2Sopenharmony_ci * See the License for the specific language governing permissions and
1350a07fd2Sopenharmony_ci * limitations under the License.
1450a07fd2Sopenharmony_ci */
1550a07fd2Sopenharmony_ci
1650a07fd2Sopenharmony_ci#include "daudio_manager_callback.h"
1750a07fd2Sopenharmony_ci
1850a07fd2Sopenharmony_ci#include <cstdint>
1950a07fd2Sopenharmony_ci#include <hdf_base.h>
2050a07fd2Sopenharmony_ci#include <securec.h>
2150a07fd2Sopenharmony_ci
2250a07fd2Sopenharmony_ci#include "audio_types.h"
2350a07fd2Sopenharmony_ci
2450a07fd2Sopenharmony_ci#include "daudio_constants.h"
2550a07fd2Sopenharmony_ci#include "daudio_errorcode.h"
2650a07fd2Sopenharmony_ci#include "daudio_log.h"
2750a07fd2Sopenharmony_ci
2850a07fd2Sopenharmony_ci#undef DH_LOG_TAG
2950a07fd2Sopenharmony_ci#define DH_LOG_TAG "DAudioManagerCallback"
3050a07fd2Sopenharmony_ci
3150a07fd2Sopenharmony_ciusing OHOS::HDI::DistributedAudio::Audioext::V2_0::AudioParameter;
3250a07fd2Sopenharmony_ci
3350a07fd2Sopenharmony_cinamespace OHOS {
3450a07fd2Sopenharmony_cinamespace DistributedHardware {
3550a07fd2Sopenharmony_ciint32_t DAudioManagerCallback::CreateStream(int32_t streamId /* for multistream */)
3650a07fd2Sopenharmony_ci{
3750a07fd2Sopenharmony_ci    DHLOGI("Open device.");
3850a07fd2Sopenharmony_ci    CHECK_NULL_RETURN(callback_, HDF_FAILURE);
3950a07fd2Sopenharmony_ci    if (callback_->CreateStream(streamId) != DH_SUCCESS) {
4050a07fd2Sopenharmony_ci        DHLOGE("Call hdi callback failed.");
4150a07fd2Sopenharmony_ci        return HDF_FAILURE;
4250a07fd2Sopenharmony_ci    }
4350a07fd2Sopenharmony_ci    return HDF_SUCCESS;
4450a07fd2Sopenharmony_ci}
4550a07fd2Sopenharmony_ci
4650a07fd2Sopenharmony_ciint32_t DAudioManagerCallback::DestroyStream(int32_t streamId)
4750a07fd2Sopenharmony_ci{
4850a07fd2Sopenharmony_ci    DHLOGI("Close device.");
4950a07fd2Sopenharmony_ci    CHECK_NULL_RETURN(callback_, HDF_FAILURE);
5050a07fd2Sopenharmony_ci    if (callback_->DestroyStream(streamId) != DH_SUCCESS) {
5150a07fd2Sopenharmony_ci        DHLOGE("Rall hdi callback failed.");
5250a07fd2Sopenharmony_ci        return HDF_FAILURE;
5350a07fd2Sopenharmony_ci    }
5450a07fd2Sopenharmony_ci    return HDF_SUCCESS;
5550a07fd2Sopenharmony_ci}
5650a07fd2Sopenharmony_ci
5750a07fd2Sopenharmony_ciint32_t DAudioManagerCallback::GetAudioParamHDF(const AudioParameter& param, AudioParamHDF& paramHDF)
5850a07fd2Sopenharmony_ci{
5950a07fd2Sopenharmony_ci    paramHDF.sampleRate = static_cast<AudioSampleRate>(param.sampleRate);
6050a07fd2Sopenharmony_ci    paramHDF.channelMask = static_cast<AudioChannel>(param.channelCount);
6150a07fd2Sopenharmony_ci    switch (static_cast<AudioFormat>(param.format)) {
6250a07fd2Sopenharmony_ci        case AUDIO_FORMAT_TYPE_PCM_8_BIT:
6350a07fd2Sopenharmony_ci            paramHDF.bitFormat = AudioSampleFormat::SAMPLE_U8;
6450a07fd2Sopenharmony_ci            break;
6550a07fd2Sopenharmony_ci        case AUDIO_FORMAT_TYPE_PCM_16_BIT:
6650a07fd2Sopenharmony_ci            paramHDF.bitFormat = AudioSampleFormat::SAMPLE_S16LE;
6750a07fd2Sopenharmony_ci            break;
6850a07fd2Sopenharmony_ci        case AUDIO_FORMAT_TYPE_PCM_24_BIT:
6950a07fd2Sopenharmony_ci            paramHDF.bitFormat = AudioSampleFormat::SAMPLE_S24LE;
7050a07fd2Sopenharmony_ci            break;
7150a07fd2Sopenharmony_ci        default:
7250a07fd2Sopenharmony_ci            DHLOGE("Format [%{public}" PRIu32"] does not support conversion.", param.format);
7350a07fd2Sopenharmony_ci            return HDF_FAILURE;
7450a07fd2Sopenharmony_ci    }
7550a07fd2Sopenharmony_ci    switch (static_cast<AudioCategory>(param.streamUsage)) {
7650a07fd2Sopenharmony_ci        case AUDIO_IN_MEDIA:
7750a07fd2Sopenharmony_ci            paramHDF.streamUsage = StreamUsage::STREAM_USAGE_MEDIA;
7850a07fd2Sopenharmony_ci            break;
7950a07fd2Sopenharmony_ci        case AUDIO_IN_COMMUNICATION:
8050a07fd2Sopenharmony_ci        case AUDIO_MMAP_VOIP:
8150a07fd2Sopenharmony_ci            paramHDF.streamUsage = StreamUsage::STREAM_USAGE_VOICE_COMMUNICATION;
8250a07fd2Sopenharmony_ci            break;
8350a07fd2Sopenharmony_ci        case AUDIO_IN_RINGTONE:
8450a07fd2Sopenharmony_ci            paramHDF.streamUsage = StreamUsage::STREAM_USAGE_NOTIFICATION_RINGTONE;
8550a07fd2Sopenharmony_ci            break;
8650a07fd2Sopenharmony_ci        case AUDIO_MMAP_NOIRQ:
8750a07fd2Sopenharmony_ci            paramHDF.streamUsage = StreamUsage::STREAM_USAGE_MEDIA;
8850a07fd2Sopenharmony_ci            break;
8950a07fd2Sopenharmony_ci        default:
9050a07fd2Sopenharmony_ci            DHLOGE("Stream usage [%{public}" PRIu32"] does not support conversion.", param.streamUsage);
9150a07fd2Sopenharmony_ci            return HDF_FAILURE;
9250a07fd2Sopenharmony_ci    }
9350a07fd2Sopenharmony_ci    paramHDF.frameSize = param.frameSize;
9450a07fd2Sopenharmony_ci    paramHDF.period = param.period;
9550a07fd2Sopenharmony_ci    paramHDF.ext = param.ext;
9650a07fd2Sopenharmony_ci    paramHDF.renderFlags = static_cast<OHOS::DistributedHardware::PortOperationMode>(param.renderFlags);
9750a07fd2Sopenharmony_ci    paramHDF.capturerFlags = static_cast<OHOS::DistributedHardware::PortOperationMode>(param.capturerFlags);
9850a07fd2Sopenharmony_ci    DHLOGI("HDF Param: sample rate %{public}d, channel %{public}d, bit format %{public}d, stream "
9950a07fd2Sopenharmony_ci        "usage %{public}d, frame size %{public}" PRIu32", period %{public}" PRIu32
10050a07fd2Sopenharmony_ci        ", renderFlags %{public}d, capturerFlags %{public}d, ext {%{public}s}.", paramHDF.sampleRate,
10150a07fd2Sopenharmony_ci        paramHDF.channelMask, paramHDF.bitFormat, paramHDF.streamUsage, paramHDF.frameSize, paramHDF.period,
10250a07fd2Sopenharmony_ci        paramHDF.renderFlags, paramHDF.capturerFlags, paramHDF.ext.c_str());
10350a07fd2Sopenharmony_ci    return HDF_SUCCESS;
10450a07fd2Sopenharmony_ci}
10550a07fd2Sopenharmony_ci
10650a07fd2Sopenharmony_ciint32_t DAudioManagerCallback::SetParameters(int32_t streamId, const AudioParameter& param)
10750a07fd2Sopenharmony_ci{
10850a07fd2Sopenharmony_ci    DHLOGD("Set Parameters.");
10950a07fd2Sopenharmony_ci    CHECK_NULL_RETURN(callback_, HDF_FAILURE);
11050a07fd2Sopenharmony_ci    AudioParamHDF paramHDF;
11150a07fd2Sopenharmony_ci    int32_t ret = GetAudioParamHDF(param, paramHDF);
11250a07fd2Sopenharmony_ci    if (ret != DH_SUCCESS) {
11350a07fd2Sopenharmony_ci        DHLOGE("Get audio HDF param failed.");
11450a07fd2Sopenharmony_ci        return HDF_FAILURE;
11550a07fd2Sopenharmony_ci    }
11650a07fd2Sopenharmony_ci    ret = callback_->SetParameters(streamId, paramHDF);
11750a07fd2Sopenharmony_ci    if (ret != DH_SUCCESS) {
11850a07fd2Sopenharmony_ci        DHLOGE("Call hdi callback failed.");
11950a07fd2Sopenharmony_ci        return HDF_FAILURE;
12050a07fd2Sopenharmony_ci    }
12150a07fd2Sopenharmony_ci    return HDF_SUCCESS;
12250a07fd2Sopenharmony_ci}
12350a07fd2Sopenharmony_ci
12450a07fd2Sopenharmony_ciint32_t DAudioManagerCallback::NotifyEvent(int32_t streamId,
12550a07fd2Sopenharmony_ci    const OHOS::HDI::DistributedAudio::Audioext::V2_0::DAudioEvent& event)
12650a07fd2Sopenharmony_ci{
12750a07fd2Sopenharmony_ci    DHLOGI("Notify event.");
12850a07fd2Sopenharmony_ci    CHECK_NULL_RETURN(callback_, HDF_FAILURE);
12950a07fd2Sopenharmony_ci    AudioEvent newEvent(AudioEventType::EVENT_UNKNOWN, event.content);
13050a07fd2Sopenharmony_ci    switch (event.type) {
13150a07fd2Sopenharmony_ci        case AudioEventHDF::AUDIO_EVENT_VOLUME_SET:
13250a07fd2Sopenharmony_ci            newEvent.type = AudioEventType::VOLUME_SET;
13350a07fd2Sopenharmony_ci            break;
13450a07fd2Sopenharmony_ci        case AudioEventHDF::AUDIO_EVENT_MUTE_SET:
13550a07fd2Sopenharmony_ci            newEvent.type = AudioEventType::VOLUME_MUTE_SET;
13650a07fd2Sopenharmony_ci            break;
13750a07fd2Sopenharmony_ci        case AudioEventHDF::AUDIO_EVENT_CHANGE_PLAY_STATUS:
13850a07fd2Sopenharmony_ci            newEvent.type = AudioEventType::CHANGE_PLAY_STATUS;
13950a07fd2Sopenharmony_ci            break;
14050a07fd2Sopenharmony_ci        case AudioEventHDF::AUDIO_EVENT_MMAP_START_SPK:
14150a07fd2Sopenharmony_ci            newEvent.type = AudioEventType::MMAP_SPK_START;
14250a07fd2Sopenharmony_ci            break;
14350a07fd2Sopenharmony_ci        case AudioEventHDF::AUDIO_EVENT_MMAP_STOP_SPK:
14450a07fd2Sopenharmony_ci            newEvent.type = AudioEventType::MMAP_SPK_STOP;
14550a07fd2Sopenharmony_ci            break;
14650a07fd2Sopenharmony_ci        case AudioEventHDF::AUDIO_EVENT_MMAP_START_MIC:
14750a07fd2Sopenharmony_ci            newEvent.type = AudioEventType::MMAP_MIC_START;
14850a07fd2Sopenharmony_ci            break;
14950a07fd2Sopenharmony_ci        case AudioEventHDF::AUDIO_EVENT_MMAP_STOP_MIC:
15050a07fd2Sopenharmony_ci            newEvent.type = AudioEventType::MMAP_MIC_STOP;
15150a07fd2Sopenharmony_ci            break;
15250a07fd2Sopenharmony_ci        case AudioEventHDF::AUDIO_EVENT_START:
15350a07fd2Sopenharmony_ci            newEvent.type = AudioEventType::AUDIO_START;
15450a07fd2Sopenharmony_ci            break;
15550a07fd2Sopenharmony_ci        case AudioEventHDF::AUDIO_EVENT_STOP:
15650a07fd2Sopenharmony_ci            newEvent.type = AudioEventType::AUDIO_STOP;
15750a07fd2Sopenharmony_ci            break;
15850a07fd2Sopenharmony_ci        default:
15950a07fd2Sopenharmony_ci            DHLOGE("Unsupport event tpye.");
16050a07fd2Sopenharmony_ci            break;
16150a07fd2Sopenharmony_ci    }
16250a07fd2Sopenharmony_ci
16350a07fd2Sopenharmony_ci    int32_t ret = callback_->NotifyEvent(streamId, newEvent);
16450a07fd2Sopenharmony_ci    if (ret != DH_SUCCESS) {
16550a07fd2Sopenharmony_ci        DHLOGE("Call hdi callback failed.");
16650a07fd2Sopenharmony_ci        return HDF_FAILURE;
16750a07fd2Sopenharmony_ci    }
16850a07fd2Sopenharmony_ci    return HDF_SUCCESS;
16950a07fd2Sopenharmony_ci}
17050a07fd2Sopenharmony_ci
17150a07fd2Sopenharmony_ciint32_t DAudioManagerCallback::WriteStreamData(int32_t streamId,
17250a07fd2Sopenharmony_ci    const OHOS::HDI::DistributedAudio::Audioext::V2_0::AudioData &data)
17350a07fd2Sopenharmony_ci{
17450a07fd2Sopenharmony_ci    DHLOGD("Write Stream Data, audio data param frameSize is %{public}d.", data.param.frameSize);
17550a07fd2Sopenharmony_ci    if (data.param.frameSize == 0 || data.param.frameSize > DEFAULT_AUDIO_DATA_SIZE) {
17650a07fd2Sopenharmony_ci        DHLOGE("Audio data param frameSize is 0. or > 4096");
17750a07fd2Sopenharmony_ci        return HDF_FAILURE;
17850a07fd2Sopenharmony_ci    }
17950a07fd2Sopenharmony_ci
18050a07fd2Sopenharmony_ci    std::shared_ptr<AudioData> audioData = std::make_shared<AudioData>(data.param.frameSize);
18150a07fd2Sopenharmony_ci    int32_t ret = memcpy_s(audioData->Data(), audioData->Capacity(), data.data.data(), data.data.size());
18250a07fd2Sopenharmony_ci    if (ret != EOK) {
18350a07fd2Sopenharmony_ci        DHLOGE("Copy audio data failed, error code %{public}d.", ret);
18450a07fd2Sopenharmony_ci        return HDF_FAILURE;
18550a07fd2Sopenharmony_ci    }
18650a07fd2Sopenharmony_ci
18750a07fd2Sopenharmony_ci    CHECK_NULL_RETURN(callback_, HDF_FAILURE);
18850a07fd2Sopenharmony_ci    if (callback_->WriteStreamData(streamId, audioData) != DH_SUCCESS) {
18950a07fd2Sopenharmony_ci        DHLOGE("WriteStreamData failed.");
19050a07fd2Sopenharmony_ci        return HDF_FAILURE;
19150a07fd2Sopenharmony_ci    }
19250a07fd2Sopenharmony_ci    return HDF_SUCCESS;
19350a07fd2Sopenharmony_ci}
19450a07fd2Sopenharmony_ci
19550a07fd2Sopenharmony_ciint32_t DAudioManagerCallback::ReadStreamData(int32_t streamId,
19650a07fd2Sopenharmony_ci    OHOS::HDI::DistributedAudio::Audioext::V2_0::AudioData &data)
19750a07fd2Sopenharmony_ci{
19850a07fd2Sopenharmony_ci    DHLOGD("Read stream data.");
19950a07fd2Sopenharmony_ci    std::shared_ptr<AudioData> audioData = nullptr;
20050a07fd2Sopenharmony_ci    CHECK_NULL_RETURN(callback_, HDF_FAILURE);
20150a07fd2Sopenharmony_ci    if (callback_->ReadStreamData(streamId, audioData) != DH_SUCCESS) {
20250a07fd2Sopenharmony_ci        DHLOGE("Read stream data failed.");
20350a07fd2Sopenharmony_ci        return HDF_FAILURE;
20450a07fd2Sopenharmony_ci    }
20550a07fd2Sopenharmony_ci
20650a07fd2Sopenharmony_ci    CHECK_NULL_RETURN(audioData, HDF_FAILURE);
20750a07fd2Sopenharmony_ci    data.data.assign(audioData->Data(), audioData->Data()+audioData->Capacity());
20850a07fd2Sopenharmony_ci    DHLOGD("Read stream data success.");
20950a07fd2Sopenharmony_ci    return HDF_SUCCESS;
21050a07fd2Sopenharmony_ci}
21150a07fd2Sopenharmony_ci
21250a07fd2Sopenharmony_ciint32_t DAudioManagerCallback::ReadMmapPosition(int32_t streamId,
21350a07fd2Sopenharmony_ci    uint64_t &frames, OHOS::HDI::DistributedAudio::Audioext::V2_0::CurrentTime &time)
21450a07fd2Sopenharmony_ci{
21550a07fd2Sopenharmony_ci    DHLOGD("Read mmap position");
21650a07fd2Sopenharmony_ci    CurrentTimeHDF timeHdf;
21750a07fd2Sopenharmony_ci    CHECK_NULL_RETURN(callback_, HDF_FAILURE);
21850a07fd2Sopenharmony_ci    if (callback_->ReadMmapPosition(streamId, frames, timeHdf) != DH_SUCCESS) {
21950a07fd2Sopenharmony_ci        DHLOGE("Read mmap position failed.");
22050a07fd2Sopenharmony_ci        return HDF_FAILURE;
22150a07fd2Sopenharmony_ci    }
22250a07fd2Sopenharmony_ci    time.tvSec = timeHdf.tvSec;
22350a07fd2Sopenharmony_ci    time.tvNSec = timeHdf.tvNSec;
22450a07fd2Sopenharmony_ci    DHLOGD("Read mmap position success.");
22550a07fd2Sopenharmony_ci    return HDF_SUCCESS;
22650a07fd2Sopenharmony_ci}
22750a07fd2Sopenharmony_ci
22850a07fd2Sopenharmony_ciint32_t DAudioManagerCallback::RefreshAshmemInfo(int32_t streamId, int fd, int32_t ashmemLength,
22950a07fd2Sopenharmony_ci    int32_t lengthPerTrans)
23050a07fd2Sopenharmony_ci{
23150a07fd2Sopenharmony_ci    DHLOGD("Refresh ashmem info.");
23250a07fd2Sopenharmony_ci    CHECK_NULL_RETURN(callback_, HDF_FAILURE);
23350a07fd2Sopenharmony_ci    if (callback_->RefreshAshmemInfo(streamId, fd, ashmemLength, lengthPerTrans) != DH_SUCCESS) {
23450a07fd2Sopenharmony_ci        DHLOGE("Refresh ashmem info failed.");
23550a07fd2Sopenharmony_ci        return HDF_FAILURE;
23650a07fd2Sopenharmony_ci    }
23750a07fd2Sopenharmony_ci    DHLOGD("Refresh ashmem info success.");
23850a07fd2Sopenharmony_ci    return HDF_SUCCESS;
23950a07fd2Sopenharmony_ci}
24050a07fd2Sopenharmony_ci} // DistributedHardware
24150a07fd2Sopenharmony_ci} // OHOS
242