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 "dspeaker_client.h"
1750a07fd2Sopenharmony_ci
1850a07fd2Sopenharmony_ci#include "cJSON.h"
1950a07fd2Sopenharmony_ci
2050a07fd2Sopenharmony_ci#include "daudio_constants.h"
2150a07fd2Sopenharmony_ci#include "daudio_hisysevent.h"
2250a07fd2Sopenharmony_ci#include "daudio_sink_hidumper.h"
2350a07fd2Sopenharmony_ci#include "daudio_util.h"
2450a07fd2Sopenharmony_ci#include "daudio_sink_manager.h"
2550a07fd2Sopenharmony_ci
2650a07fd2Sopenharmony_ci#undef DH_LOG_TAG
2750a07fd2Sopenharmony_ci#define DH_LOG_TAG "DSpeakerClient"
2850a07fd2Sopenharmony_ci
2950a07fd2Sopenharmony_cinamespace OHOS {
3050a07fd2Sopenharmony_cinamespace DistributedHardware {
3150a07fd2Sopenharmony_ciDSpeakerClient::~DSpeakerClient()
3250a07fd2Sopenharmony_ci{
3350a07fd2Sopenharmony_ci    DHLOGD("Release speaker client.");
3450a07fd2Sopenharmony_ci}
3550a07fd2Sopenharmony_ci
3650a07fd2Sopenharmony_civoid DSpeakerClient::OnEngineTransEvent(const AVTransEvent &event)
3750a07fd2Sopenharmony_ci{
3850a07fd2Sopenharmony_ci    if (event.type == EventType::EVENT_START_SUCCESS) {
3950a07fd2Sopenharmony_ci        OnStateChange(DATA_OPENED);
4050a07fd2Sopenharmony_ci    } else if ((event.type == EventType::EVENT_STOP_SUCCESS) ||
4150a07fd2Sopenharmony_ci        (event.type == EventType::EVENT_CHANNEL_CLOSED) ||
4250a07fd2Sopenharmony_ci        (event.type == EventType::EVENT_START_FAIL)) {
4350a07fd2Sopenharmony_ci        OnStateChange(DATA_CLOSED);
4450a07fd2Sopenharmony_ci    }
4550a07fd2Sopenharmony_ci}
4650a07fd2Sopenharmony_ci
4750a07fd2Sopenharmony_civoid DSpeakerClient::OnEngineTransMessage(const std::shared_ptr<AVTransMessage> &message)
4850a07fd2Sopenharmony_ci{
4950a07fd2Sopenharmony_ci    CHECK_NULL_VOID(message);
5050a07fd2Sopenharmony_ci    DHLOGI("On Engine message, type : %{public}s.", GetEventNameByType(message->type_).c_str());
5150a07fd2Sopenharmony_ci    DAudioSinkManager::GetInstance().HandleDAudioNotify(message->dstDevId_, message->dstDevId_,
5250a07fd2Sopenharmony_ci        static_cast<int32_t>(message->type_), message->content_);
5350a07fd2Sopenharmony_ci}
5450a07fd2Sopenharmony_ci
5550a07fd2Sopenharmony_civoid DSpeakerClient::OnEngineTransDataAvailable(const std::shared_ptr<AudioData> &audioData)
5650a07fd2Sopenharmony_ci{
5750a07fd2Sopenharmony_ci    DHLOGI("On Engine Data available");
5850a07fd2Sopenharmony_ci    OnDecodeTransDataDone(audioData);
5950a07fd2Sopenharmony_ci}
6050a07fd2Sopenharmony_ci
6150a07fd2Sopenharmony_ciint32_t DSpeakerClient::InitReceiverEngine(IAVEngineProvider *providerPtr)
6250a07fd2Sopenharmony_ci{
6350a07fd2Sopenharmony_ci    DHLOGI("InitReceiverEngine enter.");
6450a07fd2Sopenharmony_ci    if (speakerTrans_ == nullptr) {
6550a07fd2Sopenharmony_ci        speakerTrans_ = std::make_shared<AVTransReceiverTransport>(devId_, shared_from_this());
6650a07fd2Sopenharmony_ci    }
6750a07fd2Sopenharmony_ci    int32_t ret = speakerTrans_->InitEngine(providerPtr);
6850a07fd2Sopenharmony_ci    if (ret != DH_SUCCESS) {
6950a07fd2Sopenharmony_ci        DHLOGE("Spk client initialize av receiver adapter failed.");
7050a07fd2Sopenharmony_ci        return ERR_DH_AUDIO_NULLPTR;
7150a07fd2Sopenharmony_ci    }
7250a07fd2Sopenharmony_ci    return DH_SUCCESS;
7350a07fd2Sopenharmony_ci}
7450a07fd2Sopenharmony_ci
7550a07fd2Sopenharmony_ciint32_t DSpeakerClient::CreateAudioRenderer(const AudioParam &param)
7650a07fd2Sopenharmony_ci{
7750a07fd2Sopenharmony_ci    DHLOGD("Set up spk client: {sampleRate: %{public}d, bitFormat: %{public}d, channelMask: %{public}d,"
7850a07fd2Sopenharmony_ci        "frameSize: %{public}d, contentType: %{public}d, renderFlags: %{public}d, streamUsage: %{public}d}.",
7950a07fd2Sopenharmony_ci        param.comParam.sampleRate, param.comParam.bitFormat, param.comParam.channelMask, param.comParam.frameSize,
8050a07fd2Sopenharmony_ci        param.renderOpts.contentType, param.renderOpts.renderFlags, param.renderOpts.streamUsage);
8150a07fd2Sopenharmony_ci    audioParam_ = param;
8250a07fd2Sopenharmony_ci    AudioStandard::AudioRendererOptions rendererOptions = {
8350a07fd2Sopenharmony_ci        {
8450a07fd2Sopenharmony_ci            static_cast<AudioStandard::AudioSamplingRate>(audioParam_.comParam.sampleRate),
8550a07fd2Sopenharmony_ci            AudioStandard::AudioEncodingType::ENCODING_PCM,
8650a07fd2Sopenharmony_ci            static_cast<AudioStandard::AudioSampleFormat>(audioParam_.comParam.bitFormat),
8750a07fd2Sopenharmony_ci            static_cast<AudioStandard::AudioChannel>(audioParam_.comParam.channelMask),
8850a07fd2Sopenharmony_ci        },
8950a07fd2Sopenharmony_ci        {
9050a07fd2Sopenharmony_ci            static_cast<AudioStandard::ContentType>(audioParam_.renderOpts.contentType),
9150a07fd2Sopenharmony_ci            static_cast<AudioStandard::StreamUsage>(audioParam_.renderOpts.streamUsage),
9250a07fd2Sopenharmony_ci            audioParam_.renderOpts.renderFlags == MMAP_MODE ? AudioStandard::STREAM_FLAG_FAST : 0,
9350a07fd2Sopenharmony_ci        }
9450a07fd2Sopenharmony_ci    };
9550a07fd2Sopenharmony_ci    std::lock_guard<std::mutex> lck(devMtx_);
9650a07fd2Sopenharmony_ci    audioRenderer_ = AudioStandard::AudioRenderer::Create(rendererOptions);
9750a07fd2Sopenharmony_ci    CHECK_NULL_RETURN(audioRenderer_, ERR_DH_AUDIO_CLIENT_RENDER_CREATE_FAILED);
9850a07fd2Sopenharmony_ci
9950a07fd2Sopenharmony_ci    audioRenderer_ ->SetRendererCallback(shared_from_this());
10050a07fd2Sopenharmony_ci    if (audioParam_.renderOpts.renderFlags != MMAP_MODE) {
10150a07fd2Sopenharmony_ci        return DH_SUCCESS;
10250a07fd2Sopenharmony_ci    }
10350a07fd2Sopenharmony_ci    int32_t ret = audioRenderer_->SetRendererWriteCallback(shared_from_this());
10450a07fd2Sopenharmony_ci    if (ret != DH_SUCCESS) {
10550a07fd2Sopenharmony_ci        DHLOGE("Client save write callback failed.");
10650a07fd2Sopenharmony_ci        return ERR_DH_AUDIO_CLIENT_RENDER_CREATE_FAILED;
10750a07fd2Sopenharmony_ci    }
10850a07fd2Sopenharmony_ci    return DH_SUCCESS;
10950a07fd2Sopenharmony_ci}
11050a07fd2Sopenharmony_ci
11150a07fd2Sopenharmony_civoid DSpeakerClient::OnWriteData(size_t length)
11250a07fd2Sopenharmony_ci{
11350a07fd2Sopenharmony_ci    AudioStandard::BufferDesc bufDesc;
11450a07fd2Sopenharmony_ci    CHECK_NULL_VOID(audioRenderer_);
11550a07fd2Sopenharmony_ci    if (audioRenderer_->GetBufferDesc(bufDesc) != DH_SUCCESS || bufDesc.bufLength == 0) {
11650a07fd2Sopenharmony_ci        DHLOGE("Get buffer desc failed.");
11750a07fd2Sopenharmony_ci        return;
11850a07fd2Sopenharmony_ci    }
11950a07fd2Sopenharmony_ci    CHECK_NULL_VOID(bufDesc.buffer);
12050a07fd2Sopenharmony_ci
12150a07fd2Sopenharmony_ci    std::shared_ptr<AudioData> audioData = nullptr;
12250a07fd2Sopenharmony_ci    {
12350a07fd2Sopenharmony_ci        std::unique_lock<std::mutex> spkLck(dataQueueMtx_);
12450a07fd2Sopenharmony_ci        if (dataQueue_.empty()) {
12550a07fd2Sopenharmony_ci            audioData = std::make_shared<AudioData>(bufDesc.bufLength);
12650a07fd2Sopenharmony_ci            DHLOGD("Pop spk data, dataQueue is empty. write empty data.");
12750a07fd2Sopenharmony_ci        } else {
12850a07fd2Sopenharmony_ci            audioData = dataQueue_.front();
12950a07fd2Sopenharmony_ci            dataQueue_.pop();
13050a07fd2Sopenharmony_ci            uint64_t queueSize = static_cast<uint64_t>(dataQueue_.size());
13150a07fd2Sopenharmony_ci            DHLOGD("Pop spk data, dataQueue size: %{public}" PRIu64, queueSize);
13250a07fd2Sopenharmony_ci        }
13350a07fd2Sopenharmony_ci    }
13450a07fd2Sopenharmony_ci    if ((audioData != nullptr) && (audioData->Capacity() != bufDesc.bufLength)) {
13550a07fd2Sopenharmony_ci        uint64_t capacity = static_cast<uint64_t>(audioData->Capacity());
13650a07fd2Sopenharmony_ci        uint64_t bufLength = static_cast<uint64_t>(bufDesc.bufLength);
13750a07fd2Sopenharmony_ci        DHLOGE("Audio data length is not equal to buflength. datalength: %{public}" PRIu64
13850a07fd2Sopenharmony_ci            ", bufLength: %{public}" PRIu64, capacity, bufLength);
13950a07fd2Sopenharmony_ci    }
14050a07fd2Sopenharmony_ci    if (memcpy_s(bufDesc.buffer, bufDesc.bufLength, audioData->Data(), audioData->Capacity()) != EOK) {
14150a07fd2Sopenharmony_ci        DHLOGE("Copy audio data failed.");
14250a07fd2Sopenharmony_ci    }
14350a07fd2Sopenharmony_ci    audioRenderer_->Enqueue(bufDesc);
14450a07fd2Sopenharmony_ci}
14550a07fd2Sopenharmony_ci
14650a07fd2Sopenharmony_ciint32_t DSpeakerClient::SetUp(const AudioParam &param)
14750a07fd2Sopenharmony_ci{
14850a07fd2Sopenharmony_ci    int32_t ret = CreateAudioRenderer(param);
14950a07fd2Sopenharmony_ci    if (ret != DH_SUCCESS) {
15050a07fd2Sopenharmony_ci        DHLOGE("Set up failed, Create Audio renderer failed.");
15150a07fd2Sopenharmony_ci        return ret;
15250a07fd2Sopenharmony_ci    }
15350a07fd2Sopenharmony_ci    DumpFileUtil::OpenDumpFile(DUMP_SERVER_PARA, DUMP_DAUDIO_SPK_AFTER_TRANS_NAME, &dumpFile_);
15450a07fd2Sopenharmony_ci    CHECK_NULL_RETURN(speakerTrans_, ERR_DH_AUDIO_NULLPTR);
15550a07fd2Sopenharmony_ci    ret = speakerTrans_->SetUp(audioParam_, audioParam_, shared_from_this(), CAP_SPK);
15650a07fd2Sopenharmony_ci    if (ret != DH_SUCCESS) {
15750a07fd2Sopenharmony_ci        DHLOGE("Speaker trans setup failed.");
15850a07fd2Sopenharmony_ci        return ret;
15950a07fd2Sopenharmony_ci    }
16050a07fd2Sopenharmony_ci    ret = speakerTrans_->Start();
16150a07fd2Sopenharmony_ci    if (ret != DH_SUCCESS) {
16250a07fd2Sopenharmony_ci        DHLOGE("Speaker trans start failed.");
16350a07fd2Sopenharmony_ci        return ret;
16450a07fd2Sopenharmony_ci    }
16550a07fd2Sopenharmony_ci    auto pid = getprocpid();
16650a07fd2Sopenharmony_ci    ret = AudioStandard::AudioSystemManager::GetInstance()->RegisterVolumeKeyEventCallback(pid, shared_from_this());
16750a07fd2Sopenharmony_ci    if (ret != DH_SUCCESS) {
16850a07fd2Sopenharmony_ci        DHLOGE("Failed to register volume key event callback.");
16950a07fd2Sopenharmony_ci        return ret;
17050a07fd2Sopenharmony_ci    }
17150a07fd2Sopenharmony_ci    clientStatus_ = AudioStatus::STATUS_READY;
17250a07fd2Sopenharmony_ci    return DH_SUCCESS;
17350a07fd2Sopenharmony_ci}
17450a07fd2Sopenharmony_ci
17550a07fd2Sopenharmony_ciint32_t DSpeakerClient::Release()
17650a07fd2Sopenharmony_ci{
17750a07fd2Sopenharmony_ci    DHLOGI("Release spk client.");
17850a07fd2Sopenharmony_ci    std::lock_guard<std::mutex> lck(devMtx_);
17950a07fd2Sopenharmony_ci    if (clientStatus_ != AudioStatus::STATUS_READY && clientStatus_ != AudioStatus::STATUS_STOP) {
18050a07fd2Sopenharmony_ci        DHLOGE("Speaker status %{public}d is wrong.", (int32_t)clientStatus_);
18150a07fd2Sopenharmony_ci        return ERR_DH_AUDIO_SA_STATUS_ERR;
18250a07fd2Sopenharmony_ci    }
18350a07fd2Sopenharmony_ci    bool isSucess = true;
18450a07fd2Sopenharmony_ci    if (speakerTrans_ != nullptr) {
18550a07fd2Sopenharmony_ci        if (speakerTrans_->Stop() != DH_SUCCESS) {
18650a07fd2Sopenharmony_ci            DHLOGE("Speaker trans stop failed.");
18750a07fd2Sopenharmony_ci            isSucess = false;
18850a07fd2Sopenharmony_ci        }
18950a07fd2Sopenharmony_ci        if (speakerTrans_->Release() != DH_SUCCESS) {
19050a07fd2Sopenharmony_ci            DHLOGE("Speaker trans release failed.");
19150a07fd2Sopenharmony_ci            isSucess = false;
19250a07fd2Sopenharmony_ci        }
19350a07fd2Sopenharmony_ci        speakerTrans_ = nullptr;
19450a07fd2Sopenharmony_ci    }
19550a07fd2Sopenharmony_ci
19650a07fd2Sopenharmony_ci    int32_t ret = AudioStandard::AudioSystemManager::GetInstance()->UnregisterVolumeKeyEventCallback(getprocpid());
19750a07fd2Sopenharmony_ci    if (ret != DH_SUCCESS) {
19850a07fd2Sopenharmony_ci        DHLOGE("Failed to unregister volume key event callback, error code %{public}d.", ret);
19950a07fd2Sopenharmony_ci        isSucess = false;
20050a07fd2Sopenharmony_ci    }
20150a07fd2Sopenharmony_ci    if (audioRenderer_ != nullptr && !audioRenderer_->Release()) {
20250a07fd2Sopenharmony_ci        DHLOGE("Audio renderer release failed.");
20350a07fd2Sopenharmony_ci        isSucess = false;
20450a07fd2Sopenharmony_ci        audioRenderer_ = nullptr;
20550a07fd2Sopenharmony_ci    }
20650a07fd2Sopenharmony_ci    clientStatus_ = AudioStatus::STATUS_IDLE;
20750a07fd2Sopenharmony_ci    DumpFileUtil::CloseDumpFile(&dumpFile_);
20850a07fd2Sopenharmony_ci    return isSucess ? DH_SUCCESS : ERR_DH_AUDIO_CLIENT_RENDER_RELEASE_FAILED;
20950a07fd2Sopenharmony_ci}
21050a07fd2Sopenharmony_ci
21150a07fd2Sopenharmony_ciint32_t DSpeakerClient::StartRender()
21250a07fd2Sopenharmony_ci{
21350a07fd2Sopenharmony_ci    DHLOGI("Start spk client.");
21450a07fd2Sopenharmony_ci    std::lock_guard<std::mutex> lck(devMtx_);
21550a07fd2Sopenharmony_ci    CHECK_NULL_RETURN(audioRenderer_, ERR_DH_AUDIO_SA_STATUS_ERR);
21650a07fd2Sopenharmony_ci
21750a07fd2Sopenharmony_ci    if (!audioRenderer_->Start()) {
21850a07fd2Sopenharmony_ci        DHLOGE("Audio renderer start failed.");
21950a07fd2Sopenharmony_ci        DAudioHisysevent::GetInstance().SysEventWriteFault(DAUDIO_OPT_FAIL, ERR_DH_AUDIO_CLIENT_RENDER_STARTUP_FAILURE,
22050a07fd2Sopenharmony_ci            "daudio renderer start failed.");
22150a07fd2Sopenharmony_ci        return ERR_DH_AUDIO_CLIENT_RENDER_STARTUP_FAILURE;
22250a07fd2Sopenharmony_ci    }
22350a07fd2Sopenharmony_ci    if (audioParam_.renderOpts.renderFlags != MMAP_MODE) {
22450a07fd2Sopenharmony_ci        isRenderReady_.store(true);
22550a07fd2Sopenharmony_ci        renderDataThread_ = std::thread([this]() { this->PlayThreadRunning(); });
22650a07fd2Sopenharmony_ci    }
22750a07fd2Sopenharmony_ci    clientStatus_ = AudioStatus::STATUS_START;
22850a07fd2Sopenharmony_ci    return DH_SUCCESS;
22950a07fd2Sopenharmony_ci}
23050a07fd2Sopenharmony_ci
23150a07fd2Sopenharmony_ciint32_t DSpeakerClient::StopRender()
23250a07fd2Sopenharmony_ci{
23350a07fd2Sopenharmony_ci    DHLOGI("Stop spk client.");
23450a07fd2Sopenharmony_ci    std::lock_guard<std::mutex> lck(devMtx_);
23550a07fd2Sopenharmony_ci    if (clientStatus_ != AudioStatus::STATUS_START) {
23650a07fd2Sopenharmony_ci        DHLOGE("Renderer is not start or spk status wrong, status: %{public}d.", (int32_t)clientStatus_);
23750a07fd2Sopenharmony_ci        DAudioHisysevent::GetInstance().SysEventWriteFault(DAUDIO_OPT_FAIL, ERR_DH_AUDIO_SA_STATUS_ERR,
23850a07fd2Sopenharmony_ci            "daudio renderer is not start or spk status wrong.");
23950a07fd2Sopenharmony_ci        return ERR_DH_AUDIO_SA_STATUS_ERR;
24050a07fd2Sopenharmony_ci    }
24150a07fd2Sopenharmony_ci    if (audioRenderer_ == nullptr) {
24250a07fd2Sopenharmony_ci        DHLOGE("Audio renderer is nullptr.");
24350a07fd2Sopenharmony_ci        DAudioHisysevent::GetInstance().SysEventWriteFault(DAUDIO_OPT_FAIL, ERR_DH_AUDIO_NULLPTR,
24450a07fd2Sopenharmony_ci            "daudio renderer is nullptr.");
24550a07fd2Sopenharmony_ci        return ERR_DH_AUDIO_NULLPTR;
24650a07fd2Sopenharmony_ci    }
24750a07fd2Sopenharmony_ci
24850a07fd2Sopenharmony_ci    if (audioParam_.renderOpts.renderFlags != MMAP_MODE) {
24950a07fd2Sopenharmony_ci        if (isRenderReady_.load()) {
25050a07fd2Sopenharmony_ci            isRenderReady_.store(false);
25150a07fd2Sopenharmony_ci            if (renderDataThread_.joinable()) {
25250a07fd2Sopenharmony_ci                renderDataThread_.join();
25350a07fd2Sopenharmony_ci            }
25450a07fd2Sopenharmony_ci        }
25550a07fd2Sopenharmony_ci    }
25650a07fd2Sopenharmony_ci
25750a07fd2Sopenharmony_ci    if (!audioRenderer_->Stop()) {
25850a07fd2Sopenharmony_ci        DHLOGE("Audio renderer stop failed");
25950a07fd2Sopenharmony_ci        DAudioHisysevent::GetInstance().SysEventWriteFault(DAUDIO_OPT_FAIL, ERR_DH_AUDIO_CLIENT_RENDER_STOP_FAILED,
26050a07fd2Sopenharmony_ci            "daudio renderer stop failed.");
26150a07fd2Sopenharmony_ci        return ERR_DH_AUDIO_CLIENT_RENDER_STOP_FAILED;
26250a07fd2Sopenharmony_ci    }
26350a07fd2Sopenharmony_ci    clientStatus_ = AudioStatus::STATUS_STOP;
26450a07fd2Sopenharmony_ci    return DH_SUCCESS;
26550a07fd2Sopenharmony_ci}
26650a07fd2Sopenharmony_ci
26750a07fd2Sopenharmony_civoid DSpeakerClient::PlayThreadRunning()
26850a07fd2Sopenharmony_ci{
26950a07fd2Sopenharmony_ci    DHLOGD("Start the renderer thread.");
27050a07fd2Sopenharmony_ci    if (pthread_setname_np(pthread_self(), RENDERTHREAD) != DH_SUCCESS) {
27150a07fd2Sopenharmony_ci        DHLOGE("Render data thread setname failed.");
27250a07fd2Sopenharmony_ci    }
27350a07fd2Sopenharmony_ci
27450a07fd2Sopenharmony_ci    FillJitterQueue();
27550a07fd2Sopenharmony_ci    while (audioRenderer_ != nullptr && isRenderReady_.load()) {
27650a07fd2Sopenharmony_ci        int64_t startTime = GetNowTimeUs();
27750a07fd2Sopenharmony_ci        std::shared_ptr<AudioData> audioData = nullptr;
27850a07fd2Sopenharmony_ci        {
27950a07fd2Sopenharmony_ci            std::unique_lock<std::mutex> spkLck(dataQueueMtx_);
28050a07fd2Sopenharmony_ci            dataQueueCond_.wait_for(spkLck, std::chrono::milliseconds(REQUEST_DATA_WAIT),
28150a07fd2Sopenharmony_ci                [this]() { return !dataQueue_.empty(); });
28250a07fd2Sopenharmony_ci            if (dataQueue_.empty()) {
28350a07fd2Sopenharmony_ci                continue;
28450a07fd2Sopenharmony_ci            }
28550a07fd2Sopenharmony_ci            audioData = dataQueue_.front();
28650a07fd2Sopenharmony_ci            dataQueue_.pop();
28750a07fd2Sopenharmony_ci            uint64_t queueSize = static_cast<uint64_t>(dataQueue_.size());
28850a07fd2Sopenharmony_ci            DHLOGD("Pop spk data, dataqueue size: %{public}" PRIu64, queueSize);
28950a07fd2Sopenharmony_ci        }
29050a07fd2Sopenharmony_ci        if (audioData == nullptr) {
29150a07fd2Sopenharmony_ci            continue;
29250a07fd2Sopenharmony_ci        }
29350a07fd2Sopenharmony_ci        DumpFileUtil::WriteDumpFile(dumpFile_, static_cast<void *>(audioData->Data()), audioData->Size());
29450a07fd2Sopenharmony_ci        int32_t writeOffSet = 0;
29550a07fd2Sopenharmony_ci        while (writeOffSet < static_cast<int32_t>(audioData->Capacity())) {
29650a07fd2Sopenharmony_ci            int32_t writeLen = audioRenderer_->Write(audioData->Data() + writeOffSet,
29750a07fd2Sopenharmony_ci                static_cast<int32_t>(audioData->Capacity()) - writeOffSet);
29850a07fd2Sopenharmony_ci            uint64_t capacity = static_cast<uint64_t>(audioData->Capacity());
29950a07fd2Sopenharmony_ci            DHLOGD("Write audio render, write len: %{public}d, raw len: %{public}" PRIu64", offset: %{public}d",
30050a07fd2Sopenharmony_ci                writeLen, capacity, writeOffSet);
30150a07fd2Sopenharmony_ci            if (writeLen < 0) {
30250a07fd2Sopenharmony_ci                break;
30350a07fd2Sopenharmony_ci            }
30450a07fd2Sopenharmony_ci            writeOffSet += writeLen;
30550a07fd2Sopenharmony_ci        }
30650a07fd2Sopenharmony_ci        int64_t endTime = GetNowTimeUs();
30750a07fd2Sopenharmony_ci        if (IsOutDurationRange(startTime, endTime, lastPlayStartTime_)) {
30850a07fd2Sopenharmony_ci            DHLOGE("This time play spend: %{public}" PRId64" us, The interval of play this time and "
30950a07fd2Sopenharmony_ci                "the last time: %{public}" PRId64" us", endTime - startTime, startTime - lastPlayStartTime_);
31050a07fd2Sopenharmony_ci        }
31150a07fd2Sopenharmony_ci        lastPlayStartTime_ = startTime;
31250a07fd2Sopenharmony_ci    }
31350a07fd2Sopenharmony_ci}
31450a07fd2Sopenharmony_ci
31550a07fd2Sopenharmony_civoid DSpeakerClient::FillJitterQueue()
31650a07fd2Sopenharmony_ci{
31750a07fd2Sopenharmony_ci    while (isRenderReady_.load()) {
31850a07fd2Sopenharmony_ci        {
31950a07fd2Sopenharmony_ci            std::lock_guard<std::mutex> lock(dataQueueMtx_);
32050a07fd2Sopenharmony_ci            if (dataQueue_.size() >= DATA_QUEUE_SIZE) {
32150a07fd2Sopenharmony_ci                break;
32250a07fd2Sopenharmony_ci            }
32350a07fd2Sopenharmony_ci        }
32450a07fd2Sopenharmony_ci        usleep(SLEEP_TIME);
32550a07fd2Sopenharmony_ci    }
32650a07fd2Sopenharmony_ci}
32750a07fd2Sopenharmony_ci
32850a07fd2Sopenharmony_civoid DSpeakerClient::FlushJitterQueue()
32950a07fd2Sopenharmony_ci{
33050a07fd2Sopenharmony_ci    while (isRenderReady_.load()) {
33150a07fd2Sopenharmony_ci        {
33250a07fd2Sopenharmony_ci            std::lock_guard<std::mutex> lock(dataQueueMtx_);
33350a07fd2Sopenharmony_ci            if (dataQueue_.empty()) {
33450a07fd2Sopenharmony_ci                break;
33550a07fd2Sopenharmony_ci            }
33650a07fd2Sopenharmony_ci        }
33750a07fd2Sopenharmony_ci        usleep(SLEEP_TIME);
33850a07fd2Sopenharmony_ci    }
33950a07fd2Sopenharmony_ci}
34050a07fd2Sopenharmony_ci
34150a07fd2Sopenharmony_ciint32_t DSpeakerClient::OnDecodeTransDataDone(const std::shared_ptr<AudioData> &audioData)
34250a07fd2Sopenharmony_ci{
34350a07fd2Sopenharmony_ci    DHLOGI("Write stream buffer.");
34450a07fd2Sopenharmony_ci    int64_t startTime = GetNowTimeUs();
34550a07fd2Sopenharmony_ci    CHECK_NULL_RETURN(audioData, ERR_DH_AUDIO_NULLPTR);
34650a07fd2Sopenharmony_ci
34750a07fd2Sopenharmony_ci    std::lock_guard<std::mutex> lock(dataQueueMtx_);
34850a07fd2Sopenharmony_ci    while (dataQueue_.size() > DATA_QUEUE_MAX_SIZE) {
34950a07fd2Sopenharmony_ci        DHLOGD("Data queue overflow.");
35050a07fd2Sopenharmony_ci        dataQueue_.pop();
35150a07fd2Sopenharmony_ci    }
35250a07fd2Sopenharmony_ci    dataQueue_.push(audioData);
35350a07fd2Sopenharmony_ci    dataQueueCond_.notify_all();
35450a07fd2Sopenharmony_ci    uint64_t queueSize = static_cast<uint64_t>(dataQueue_.size());
35550a07fd2Sopenharmony_ci    DHLOGD("Push new spk data, buf len: %{public}" PRIu64, queueSize);
35650a07fd2Sopenharmony_ci    int64_t endTime = GetNowTimeUs();
35750a07fd2Sopenharmony_ci    if (IsOutDurationRange(startTime, endTime, lastReceiveStartTime_)) {
35850a07fd2Sopenharmony_ci        DHLOGE("This time receivce data spend: %{public}" PRId64" us, Receivce data this time and "
35950a07fd2Sopenharmony_ci            "the last time: %{public}" PRId64" us", endTime - startTime, startTime - lastReceiveStartTime_);
36050a07fd2Sopenharmony_ci    }
36150a07fd2Sopenharmony_ci    lastReceiveStartTime_ = startTime;
36250a07fd2Sopenharmony_ci    return DH_SUCCESS;
36350a07fd2Sopenharmony_ci}
36450a07fd2Sopenharmony_ci
36550a07fd2Sopenharmony_ciint32_t DSpeakerClient::OnStateChange(const AudioEventType type)
36650a07fd2Sopenharmony_ci{
36750a07fd2Sopenharmony_ci    DHLOGD("On state change. type: %{public}d", type);
36850a07fd2Sopenharmony_ci    AudioEvent event;
36950a07fd2Sopenharmony_ci    switch (type) {
37050a07fd2Sopenharmony_ci        case AudioEventType::DATA_OPENED: {
37150a07fd2Sopenharmony_ci            event.type = AudioEventType::SPEAKER_OPENED;
37250a07fd2Sopenharmony_ci            event.content = GetVolumeLevel();
37350a07fd2Sopenharmony_ci            break;
37450a07fd2Sopenharmony_ci        }
37550a07fd2Sopenharmony_ci        case AudioEventType::DATA_CLOSED: {
37650a07fd2Sopenharmony_ci            event.type = AudioEventType::SPEAKER_CLOSED;
37750a07fd2Sopenharmony_ci            event.content = GetCJsonString(KEY_DH_ID, std::to_string(dhId_).c_str());
37850a07fd2Sopenharmony_ci            break;
37950a07fd2Sopenharmony_ci        }
38050a07fd2Sopenharmony_ci        default:
38150a07fd2Sopenharmony_ci            DHLOGE("Invalid parameter type: %{public}d.", type);
38250a07fd2Sopenharmony_ci            return ERR_DH_AUDIO_NOT_SUPPORT;
38350a07fd2Sopenharmony_ci    }
38450a07fd2Sopenharmony_ci
38550a07fd2Sopenharmony_ci    std::shared_ptr<IAudioEventCallback> cbObj = eventCallback_.lock();
38650a07fd2Sopenharmony_ci    CHECK_NULL_RETURN(cbObj, ERR_DH_AUDIO_NULLPTR);
38750a07fd2Sopenharmony_ci    cbObj->NotifyEvent(event);
38850a07fd2Sopenharmony_ci    return DH_SUCCESS;
38950a07fd2Sopenharmony_ci}
39050a07fd2Sopenharmony_ci
39150a07fd2Sopenharmony_cistring DSpeakerClient::GetVolumeLevel()
39250a07fd2Sopenharmony_ci{
39350a07fd2Sopenharmony_ci    DHLOGD("Get the volume level.");
39450a07fd2Sopenharmony_ci    AudioStandard::AudioStreamType streamType = AudioStandard::AudioStreamType::STREAM_DEFAULT;
39550a07fd2Sopenharmony_ci    auto volumeType = static_cast<AudioStandard::AudioVolumeType>(1);
39650a07fd2Sopenharmony_ci    int32_t volumeLevel = AudioStandard::AudioSystemManager::GetInstance()->GetVolume(volumeType);
39750a07fd2Sopenharmony_ci    int32_t maxVolumeLevel = AudioStandard::AudioSystemManager::GetInstance()->GetMaxVolume(volumeType);
39850a07fd2Sopenharmony_ci    int32_t minVolumeLevel = AudioStandard::AudioSystemManager::GetInstance()->GetMinVolume(volumeType);
39950a07fd2Sopenharmony_ci    bool isUpdateUi = false;
40050a07fd2Sopenharmony_ci    cJSON *jParam = cJSON_CreateObject();
40150a07fd2Sopenharmony_ci    CHECK_NULL_RETURN(jParam, "");
40250a07fd2Sopenharmony_ci
40350a07fd2Sopenharmony_ci    cJSON_AddStringToObject(jParam, KEY_DH_ID, std::to_string(dhId_).c_str());
40450a07fd2Sopenharmony_ci    cJSON_AddStringToObject(jParam, KEY_CHANGE_TYPE, FIRST_VOLUME_CHANAGE);
40550a07fd2Sopenharmony_ci    cJSON_AddStringToObject(jParam, AUDIO_STREAM_TYPE, std::to_string(streamType).c_str());
40650a07fd2Sopenharmony_ci    cJSON_AddStringToObject(jParam, VOLUME_LEVEL.c_str(), std::to_string(volumeLevel).c_str());
40750a07fd2Sopenharmony_ci    cJSON_AddStringToObject(jParam, IS_UPDATEUI, std::to_string(isUpdateUi).c_str());
40850a07fd2Sopenharmony_ci    cJSON_AddStringToObject(jParam, MAX_VOLUME_LEVEL, std::to_string(maxVolumeLevel).c_str());
40950a07fd2Sopenharmony_ci    cJSON_AddStringToObject(jParam, MIN_VOLUME_LEVEL, std::to_string(minVolumeLevel).c_str());
41050a07fd2Sopenharmony_ci    char *jsonData = cJSON_PrintUnformatted(jParam);
41150a07fd2Sopenharmony_ci    if (jsonData == nullptr) {
41250a07fd2Sopenharmony_ci        DHLOGE("Failed to create JSON data.");
41350a07fd2Sopenharmony_ci        cJSON_Delete(jParam);
41450a07fd2Sopenharmony_ci        return "";
41550a07fd2Sopenharmony_ci    }
41650a07fd2Sopenharmony_ci    std::string str(jsonData);
41750a07fd2Sopenharmony_ci    cJSON_Delete(jParam);
41850a07fd2Sopenharmony_ci    cJSON_free(jsonData);
41950a07fd2Sopenharmony_ci    DHLOGD("Get the volume level result, event: %{public}s.", str.c_str());
42050a07fd2Sopenharmony_ci    return str;
42150a07fd2Sopenharmony_ci}
42250a07fd2Sopenharmony_ci
42350a07fd2Sopenharmony_civoid DSpeakerClient::OnVolumeKeyEvent(AudioStandard::VolumeEvent volumeEvent)
42450a07fd2Sopenharmony_ci{
42550a07fd2Sopenharmony_ci    DHLOGD("Volume change event.");
42650a07fd2Sopenharmony_ci    std::shared_ptr<IAudioEventCallback> cbObj = eventCallback_.lock();
42750a07fd2Sopenharmony_ci    CHECK_NULL_VOID(cbObj);
42850a07fd2Sopenharmony_ci
42950a07fd2Sopenharmony_ci    cJSON *jParam = cJSON_CreateObject();
43050a07fd2Sopenharmony_ci    CHECK_NULL_VOID(jParam);
43150a07fd2Sopenharmony_ci
43250a07fd2Sopenharmony_ci    cJSON_AddStringToObject(jParam, KEY_DH_ID, std::to_string(dhId_).c_str());
43350a07fd2Sopenharmony_ci    cJSON_AddStringToObject(jParam, KEY_CHANGE_TYPE, VOLUME_CHANAGE);
43450a07fd2Sopenharmony_ci    cJSON_AddStringToObject(jParam, AUDIO_STREAM_TYPE, std::to_string(volumeEvent.volumeType).c_str());
43550a07fd2Sopenharmony_ci    cJSON_AddStringToObject(jParam, VOLUME_LEVEL.c_str(), std::to_string(volumeEvent.volume).c_str());
43650a07fd2Sopenharmony_ci    cJSON_AddStringToObject(jParam, IS_UPDATEUI, std::to_string(volumeEvent.updateUi).c_str());
43750a07fd2Sopenharmony_ci    cJSON_AddStringToObject(jParam, VOLUME_GROUP_ID, std::to_string(volumeEvent.volumeGroupId).c_str());
43850a07fd2Sopenharmony_ci    char *jsonData = cJSON_PrintUnformatted(jParam);
43950a07fd2Sopenharmony_ci    if (jsonData == nullptr) {
44050a07fd2Sopenharmony_ci        DHLOGE("Failed to create JSON data.");
44150a07fd2Sopenharmony_ci        cJSON_Delete(jParam);
44250a07fd2Sopenharmony_ci        return;
44350a07fd2Sopenharmony_ci    }
44450a07fd2Sopenharmony_ci    std::string str(jsonData);
44550a07fd2Sopenharmony_ci    cJSON_Delete(jParam);
44650a07fd2Sopenharmony_ci    cJSON_free(jsonData);
44750a07fd2Sopenharmony_ci    DHLOGD("Volume change notification result, event: %{public}s.", str.c_str());
44850a07fd2Sopenharmony_ci
44950a07fd2Sopenharmony_ci    AudioEvent audioEvent(VOLUME_CHANGE, str);
45050a07fd2Sopenharmony_ci    cbObj->NotifyEvent(audioEvent);
45150a07fd2Sopenharmony_ci}
45250a07fd2Sopenharmony_ci
45350a07fd2Sopenharmony_civoid DSpeakerClient::OnInterrupt(const AudioStandard::InterruptEvent &interruptEvent)
45450a07fd2Sopenharmony_ci{
45550a07fd2Sopenharmony_ci    DHLOGD("Audio focus interrupt event.");
45650a07fd2Sopenharmony_ci    std::shared_ptr<IAudioEventCallback> cbObj = eventCallback_.lock();
45750a07fd2Sopenharmony_ci    CHECK_NULL_VOID(cbObj);
45850a07fd2Sopenharmony_ci
45950a07fd2Sopenharmony_ci    cJSON *jParam = cJSON_CreateObject();
46050a07fd2Sopenharmony_ci    CHECK_NULL_VOID(jParam);
46150a07fd2Sopenharmony_ci
46250a07fd2Sopenharmony_ci    cJSON_AddStringToObject(jParam, KEY_DH_ID, std::to_string(dhId_).c_str());
46350a07fd2Sopenharmony_ci    cJSON_AddStringToObject(jParam, KEY_CHANGE_TYPE, INTERRUPT_EVENT);
46450a07fd2Sopenharmony_ci    cJSON_AddStringToObject(jParam, VOLUME_EVENT_TYPE, std::to_string(interruptEvent.eventType).c_str());
46550a07fd2Sopenharmony_ci    cJSON_AddStringToObject(jParam, FORCE_TYPE, std::to_string(interruptEvent.forceType).c_str());
46650a07fd2Sopenharmony_ci    cJSON_AddStringToObject(jParam, HINT_TYPE, std::to_string(interruptEvent.hintType).c_str());
46750a07fd2Sopenharmony_ci    char *jsonData = cJSON_PrintUnformatted(jParam);
46850a07fd2Sopenharmony_ci    if (jsonData == nullptr) {
46950a07fd2Sopenharmony_ci        DHLOGE("Failed to create JSON data.");
47050a07fd2Sopenharmony_ci        cJSON_Delete(jParam);
47150a07fd2Sopenharmony_ci        return;
47250a07fd2Sopenharmony_ci    }
47350a07fd2Sopenharmony_ci    std::string str(jsonData);
47450a07fd2Sopenharmony_ci    cJSON_Delete(jParam);
47550a07fd2Sopenharmony_ci    cJSON_free(jsonData);
47650a07fd2Sopenharmony_ci    DHLOGD("Audio focus oninterrupt notification result, event: %{public}s.", str.c_str());
47750a07fd2Sopenharmony_ci
47850a07fd2Sopenharmony_ci    AudioEvent audioEvent(AUDIO_FOCUS_CHANGE, str);
47950a07fd2Sopenharmony_ci    cbObj->NotifyEvent(audioEvent);
48050a07fd2Sopenharmony_ci}
48150a07fd2Sopenharmony_ci
48250a07fd2Sopenharmony_civoid DSpeakerClient::OnStateChange(const AudioStandard::RendererState state,
48350a07fd2Sopenharmony_ci    const AudioStandard::StateChangeCmdType __attribute__((unused)) cmdType)
48450a07fd2Sopenharmony_ci{
48550a07fd2Sopenharmony_ci    DHLOGD("On render state change. state: %{public}d", state);
48650a07fd2Sopenharmony_ci    std::shared_ptr<IAudioEventCallback> cbObj = eventCallback_.lock();
48750a07fd2Sopenharmony_ci    CHECK_NULL_VOID(cbObj);
48850a07fd2Sopenharmony_ci
48950a07fd2Sopenharmony_ci    cJSON *jParam = cJSON_CreateObject();
49050a07fd2Sopenharmony_ci    CHECK_NULL_VOID(jParam);
49150a07fd2Sopenharmony_ci
49250a07fd2Sopenharmony_ci    cJSON_AddStringToObject(jParam, KEY_DH_ID, std::to_string(dhId_).c_str());
49350a07fd2Sopenharmony_ci    cJSON_AddStringToObject(jParam, KEY_CHANGE_TYPE, RENDER_STATE_CHANGE_EVENT);
49450a07fd2Sopenharmony_ci    cJSON_AddStringToObject(jParam, KEY_STATE, std::to_string(state).c_str());
49550a07fd2Sopenharmony_ci    char *jsonData = cJSON_PrintUnformatted(jParam);
49650a07fd2Sopenharmony_ci    if (jsonData == nullptr) {
49750a07fd2Sopenharmony_ci        DHLOGE("Failed to create JSON data.");
49850a07fd2Sopenharmony_ci        cJSON_Delete(jParam);
49950a07fd2Sopenharmony_ci        return;
50050a07fd2Sopenharmony_ci    }
50150a07fd2Sopenharmony_ci    std::string str(jsonData);
50250a07fd2Sopenharmony_ci    cJSON_Delete(jParam);
50350a07fd2Sopenharmony_ci    cJSON_free(jsonData);
50450a07fd2Sopenharmony_ci    DHLOGD("Audio render state changes notification result, event: %{public}s.", str.c_str());
50550a07fd2Sopenharmony_ci
50650a07fd2Sopenharmony_ci    AudioEvent audioEvent(AUDIO_RENDER_STATE_CHANGE, str);
50750a07fd2Sopenharmony_ci    cbObj->NotifyEvent(audioEvent);
50850a07fd2Sopenharmony_ci}
50950a07fd2Sopenharmony_ci
51050a07fd2Sopenharmony_ciint32_t DSpeakerClient::SetAudioParameters(const AudioEvent &event)
51150a07fd2Sopenharmony_ci{
51250a07fd2Sopenharmony_ci    DHLOGD("Set the volume, arg: %{public}s.", event.content.c_str());
51350a07fd2Sopenharmony_ci
51450a07fd2Sopenharmony_ci    int32_t audioVolumeType;
51550a07fd2Sopenharmony_ci    int32_t ret = GetAudioParamInt(event.content, AUDIO_VOLUME_TYPE, audioVolumeType);
51650a07fd2Sopenharmony_ci    if (ret != DH_SUCCESS) {
51750a07fd2Sopenharmony_ci        DHLOGE("Get audio volume type failed.");
51850a07fd2Sopenharmony_ci        return ret;
51950a07fd2Sopenharmony_ci    }
52050a07fd2Sopenharmony_ci    auto volumeType = static_cast<AudioStandard::AudioVolumeType>(audioVolumeType);
52150a07fd2Sopenharmony_ci    DHLOGD("Audio volume type, volumeType = %{public}d.", volumeType);
52250a07fd2Sopenharmony_ci    if (event.type != VOLUME_SET) {
52350a07fd2Sopenharmony_ci        DHLOGE("Invalid parameter.");
52450a07fd2Sopenharmony_ci        return ERR_DH_AUDIO_CLIENT_PARAM_ERROR;
52550a07fd2Sopenharmony_ci    }
52650a07fd2Sopenharmony_ci
52750a07fd2Sopenharmony_ci    int32_t audioVolumeLevel;
52850a07fd2Sopenharmony_ci    ret = GetAudioParamInt(event.content, VOLUME_LEVEL, audioVolumeLevel);
52950a07fd2Sopenharmony_ci    if (ret != DH_SUCCESS) {
53050a07fd2Sopenharmony_ci        DHLOGE("Get audio volume level failed.");
53150a07fd2Sopenharmony_ci        return ret;
53250a07fd2Sopenharmony_ci    }
53350a07fd2Sopenharmony_ci    DHLOGD("volume level = %{public}d.", audioVolumeLevel);
53450a07fd2Sopenharmony_ci    ret = AudioStandard::AudioSystemManager::GetInstance()->SetVolume(volumeType, audioVolumeLevel);
53550a07fd2Sopenharmony_ci    if (ret != DH_SUCCESS) {
53650a07fd2Sopenharmony_ci        DHLOGE("Voloume set failed.");
53750a07fd2Sopenharmony_ci        return ERR_DH_AUDIO_CLIENT_SET_VOLUME_FAILED;
53850a07fd2Sopenharmony_ci    }
53950a07fd2Sopenharmony_ci    return DH_SUCCESS;
54050a07fd2Sopenharmony_ci}
54150a07fd2Sopenharmony_ci
54250a07fd2Sopenharmony_ciint32_t DSpeakerClient::SetMute(const AudioEvent &event)
54350a07fd2Sopenharmony_ci{
54450a07fd2Sopenharmony_ci    DHLOGD("Set mute, arg: %{public}s.", event.content.c_str());
54550a07fd2Sopenharmony_ci    int32_t audioVolumeType;
54650a07fd2Sopenharmony_ci    int32_t ret = GetAudioParamInt(event.content, AUDIO_VOLUME_TYPE, audioVolumeType);
54750a07fd2Sopenharmony_ci    if (ret != DH_SUCCESS) {
54850a07fd2Sopenharmony_ci        DHLOGE("Get audio volume type failed.");
54950a07fd2Sopenharmony_ci        return ret;
55050a07fd2Sopenharmony_ci    }
55150a07fd2Sopenharmony_ci
55250a07fd2Sopenharmony_ci    bool muteStatus = false;
55350a07fd2Sopenharmony_ci    ret = GetAudioParamBool(event.content, STREAM_MUTE_STATUS, muteStatus);
55450a07fd2Sopenharmony_ci    if (ret != DH_SUCCESS) {
55550a07fd2Sopenharmony_ci        DHLOGE("Get mute status failed.");
55650a07fd2Sopenharmony_ci        return ret;
55750a07fd2Sopenharmony_ci    }
55850a07fd2Sopenharmony_ci
55950a07fd2Sopenharmony_ci    auto volumeType = static_cast<AudioStandard::AudioVolumeType>(audioVolumeType);
56050a07fd2Sopenharmony_ci    DHLOGD("Audio volume type, volumeType = %{public}d.", volumeType);
56150a07fd2Sopenharmony_ci    if (event.type != VOLUME_MUTE_SET) {
56250a07fd2Sopenharmony_ci        DHLOGE("Invalid parameter.");
56350a07fd2Sopenharmony_ci        return ERR_DH_AUDIO_CLIENT_PARAM_ERROR;
56450a07fd2Sopenharmony_ci    }
56550a07fd2Sopenharmony_ci    ret = AudioStandard::AudioSystemManager::GetInstance()->SetMute(volumeType, muteStatus);
56650a07fd2Sopenharmony_ci    if (ret != DH_SUCCESS) {
56750a07fd2Sopenharmony_ci        DHLOGE("Mute set failed.");
56850a07fd2Sopenharmony_ci        return ERR_DH_AUDIO_CLIENT_SET_MUTE_FAILED;
56950a07fd2Sopenharmony_ci    }
57050a07fd2Sopenharmony_ci    return DH_SUCCESS;
57150a07fd2Sopenharmony_ci}
57250a07fd2Sopenharmony_ci
57350a07fd2Sopenharmony_civoid DSpeakerClient::Pause()
57450a07fd2Sopenharmony_ci{
57550a07fd2Sopenharmony_ci    DHLOGI("Pause and flush");
57650a07fd2Sopenharmony_ci    FlushJitterQueue();
57750a07fd2Sopenharmony_ci    if (audioParam_.renderOpts.renderFlags != MMAP_MODE) {
57850a07fd2Sopenharmony_ci        isRenderReady_.store(false);
57950a07fd2Sopenharmony_ci        if (renderDataThread_.joinable()) {
58050a07fd2Sopenharmony_ci            renderDataThread_.join();
58150a07fd2Sopenharmony_ci        }
58250a07fd2Sopenharmony_ci    }
58350a07fd2Sopenharmony_ci
58450a07fd2Sopenharmony_ci    if (speakerTrans_ == nullptr || speakerTrans_->Pause() != DH_SUCCESS) {
58550a07fd2Sopenharmony_ci        DHLOGE("Speaker trans Pause failed.");
58650a07fd2Sopenharmony_ci    }
58750a07fd2Sopenharmony_ci    if (audioRenderer_ != nullptr) {
58850a07fd2Sopenharmony_ci        audioRenderer_->Flush();
58950a07fd2Sopenharmony_ci        audioRenderer_->Pause();
59050a07fd2Sopenharmony_ci    }
59150a07fd2Sopenharmony_ci    clientStatus_ = AudioStatus::STATUS_START;
59250a07fd2Sopenharmony_ci    isRenderReady_.store(true);
59350a07fd2Sopenharmony_ci}
59450a07fd2Sopenharmony_ci
59550a07fd2Sopenharmony_civoid DSpeakerClient::ReStart()
59650a07fd2Sopenharmony_ci{
59750a07fd2Sopenharmony_ci    DHLOGI("ReStart");
59850a07fd2Sopenharmony_ci    if (speakerTrans_ == nullptr || speakerTrans_->Restart(audioParam_, audioParam_) != DH_SUCCESS) {
59950a07fd2Sopenharmony_ci        DHLOGE("Speaker trans Restart failed.");
60050a07fd2Sopenharmony_ci    }
60150a07fd2Sopenharmony_ci    if (audioParam_.renderOpts.renderFlags != MMAP_MODE) {
60250a07fd2Sopenharmony_ci        isRenderReady_.store(true);
60350a07fd2Sopenharmony_ci        renderDataThread_ = std::thread([this]() { this->PlayThreadRunning(); });
60450a07fd2Sopenharmony_ci    }
60550a07fd2Sopenharmony_ci    if (audioRenderer_ != nullptr) {
60650a07fd2Sopenharmony_ci        audioRenderer_->Start();
60750a07fd2Sopenharmony_ci    }
60850a07fd2Sopenharmony_ci    clientStatus_ = AudioStatus::STATUS_START;
60950a07fd2Sopenharmony_ci}
61050a07fd2Sopenharmony_ci
61150a07fd2Sopenharmony_ciint32_t DSpeakerClient::SendMessage(uint32_t type, std::string content, std::string dstDevId)
61250a07fd2Sopenharmony_ci{
61350a07fd2Sopenharmony_ci    DHLOGD("Send message to remote.");
61450a07fd2Sopenharmony_ci    if (type != static_cast<uint32_t>(NOTIFY_OPEN_SPEAKER_RESULT) &&
61550a07fd2Sopenharmony_ci        type != static_cast<uint32_t>(NOTIFY_OPEN_CTRL_RESULT) &&
61650a07fd2Sopenharmony_ci        type != static_cast<uint32_t>(NOTIFY_CLOSE_SPEAKER_RESULT) &&
61750a07fd2Sopenharmony_ci        type != static_cast<uint32_t>(VOLUME_CHANGE) &&
61850a07fd2Sopenharmony_ci        type != static_cast<uint32_t>(AUDIO_FOCUS_CHANGE) &&
61950a07fd2Sopenharmony_ci        type != static_cast<uint32_t>(AUDIO_RENDER_STATE_CHANGE)) {
62050a07fd2Sopenharmony_ci        DHLOGE("event type is not NOTIFY_OPEN_SPK or NOTIFY_CLOSE_SPK or OPEN_CTRL. type:%{public}u", type);
62150a07fd2Sopenharmony_ci        return ERR_DH_AUDIO_NULLPTR;
62250a07fd2Sopenharmony_ci    }
62350a07fd2Sopenharmony_ci    CHECK_NULL_RETURN(speakerTrans_, ERR_DH_AUDIO_NULLPTR);
62450a07fd2Sopenharmony_ci    speakerTrans_->SendMessage(type, content, dstDevId);
62550a07fd2Sopenharmony_ci    return DH_SUCCESS;
62650a07fd2Sopenharmony_ci}
62750a07fd2Sopenharmony_ci
62850a07fd2Sopenharmony_civoid DSpeakerClient::PlayStatusChange(const std::string &args)
62950a07fd2Sopenharmony_ci{
63050a07fd2Sopenharmony_ci    DHLOGI("Play status change, args: %{public}s.", args.c_str());
63150a07fd2Sopenharmony_ci    std::string changeType = ParseStringFromArgs(args, KEY_CHANGE_TYPE);
63250a07fd2Sopenharmony_ci    if (changeType == AUDIO_EVENT_RESTART) {
63350a07fd2Sopenharmony_ci        ReStart();
63450a07fd2Sopenharmony_ci    } else if (changeType == AUDIO_EVENT_PAUSE) {
63550a07fd2Sopenharmony_ci        Pause();
63650a07fd2Sopenharmony_ci    } else {
63750a07fd2Sopenharmony_ci        DHLOGE("Play status error.");
63850a07fd2Sopenharmony_ci    }
63950a07fd2Sopenharmony_ci}
64050a07fd2Sopenharmony_ci
64150a07fd2Sopenharmony_civoid DSpeakerClient::SetAttrs(const std::string &devId, const std::shared_ptr<IAudioEventCallback> &callback)
64250a07fd2Sopenharmony_ci{
64350a07fd2Sopenharmony_ci    DHLOGE("Set attrs, not support yet.");
64450a07fd2Sopenharmony_ci}
64550a07fd2Sopenharmony_ci} // DistributedHardware
64650a07fd2Sopenharmony_ci} // OHOS
647