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