• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef LOG_TAG
16 #define LOG_TAG "AudioLoopback"
17 #endif
18 
19 #include "audio_loopback_private.h"
20 #include "audio_manager_log.h"
21 #include "audio_errors.h"
22 #include "audio_stream_info.h"
23 #include "audio_policy_manager.h"
24 #include "securec.h"
25 #include "access_token.h"
26 #include "accesstoken_kit.h"
27 #include "ipc_skeleton.h"
28 #include "audio_utils.h"
29 namespace OHOS {
30 namespace AudioStandard {
31 namespace {
32     const int32_t VALUE_HUNDRED = 100;
33     const std::map<AudioLoopbackReverbPreset, std::string> audioLoopbackReverbPresetMap = {
34         {REVERB_PRESET_ORIGINAL, "disable"},
35         {REVERB_PRESET_KTV, "ktv"},
36         {REVERB_PRESET_THEATRE, "theatre"},
37         {REVERB_PRESET_CONCERT, "concert"},
38     };
39     const std::map<AudioLoopbackEqualizerPreset, std::string> audioLoopbackEqualizerPresetMap = {
40         {EQUALIZER_PRESET_FLAT, "disable"},
41         {EQUALIZER_PRESET_FULL, "full"},
42         {EQUALIZER_PRESET_BRIGHT, "bright"},
43     };
44 }
45 
CreateAudioLoopback(AudioLoopbackMode mode,const AppInfo & appInfo)46 std::shared_ptr<AudioLoopback> AudioLoopback::CreateAudioLoopback(AudioLoopbackMode mode, const AppInfo &appInfo)
47 {
48     Security::AccessToken::AccessTokenID tokenId = appInfo.appTokenId;
49     tokenId = (tokenId == Security::AccessToken::INVALID_TOKENID) ? IPCSkeleton::GetCallingTokenID() : tokenId;
50     int res = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, MICROPHONE_PERMISSION);
51     CHECK_AND_RETURN_RET_LOG(res == Security::AccessToken::PermissionState::PERMISSION_GRANTED,
52         nullptr, "Permission denied [tid:%{public}d]", tokenId);
53     static std::shared_ptr<AudioLoopback> instance = std::make_shared<AudioLoopbackPrivate>(mode, appInfo);
54     return instance;
55 }
56 
AudioLoopbackPrivate(AudioLoopbackMode mode,const AppInfo & appInfo)57 AudioLoopbackPrivate::AudioLoopbackPrivate(AudioLoopbackMode mode, const AppInfo &appInfo)
58 {
59     appInfo_ = appInfo;
60     if (appInfo_.appPid == 0) {
61         appInfo_.appPid = getpid();
62     }
63 
64     if (appInfo_.appUid < 0) {
65         appInfo_.appUid = static_cast<int32_t>(getuid());
66     }
67     mode_ = mode;
68     karaokeParams_["Karaoke_enable"] = "disable";
69     karaokeParams_["Karaoke_reverb_mode"] = "theatre";
70     karaokeParams_["Karaoke_eq_mode"] = "full";
71     karaokeParams_["Karaoke_volume"] = "50";
72     rendererOptions_ = GenerateRendererConfig();
73     capturerOptions_ = GenerateCapturerConfig();
74     InitStatus();
75 }
76 
77 AudioLoopback::~AudioLoopback() = default;
78 
~AudioLoopbackPrivate()79 AudioLoopbackPrivate::~AudioLoopbackPrivate()
80 {
81     AUDIO_INFO_LOG("~AudioLoopbackPrivate");
82     std::unique_lock<std::mutex> stateLock(stateMutex_);
83     CHECK_AND_RETURN_LOG(currentState_ == LOOPBACK_STATE_RUNNING, "AudioLoopback not Running");
84     currentState_ = LOOPBACK_STATE_DESTROYING;
85     stateLock.unlock();
86     DestroyAudioLoopbackInner();
87 }
88 
Enable(bool enable)89 bool AudioLoopbackPrivate::Enable(bool enable)
90 {
91     Trace trace("AudioLoopbackPrivate::Enable");
92     std::lock_guard<std::mutex> lock(loopbackMutex_);
93     CHECK_AND_RETURN_RET_LOG(IsAudioLoopbackSupported(), false, "AudioLoopback not support");
94     AUDIO_INFO_LOG("Enable %{public}d, currentState_ %{public}d", enable, currentState_);
95     if (enable) {
96         CHECK_AND_RETURN_RET_LOG(GetCurrentState() != LOOPBACK_STATE_RUNNING, true, "AudioLoopback already running");
97         InitStatus();
98         CHECK_AND_RETURN_RET_LOG(CheckDeviceSupport(), false, "Device not support");
99         CreateAudioLoopback();
100         currentState_ = LOOPBACK_STATE_PREPARED;
101         UpdateStatus();
102         CHECK_AND_RETURN_RET_LOG(GetCurrentState() == LOOPBACK_STATE_RUNNING, false, "AudioLoopback Enable failed");
103     } else {
104         std::unique_lock<std::mutex> stateLock(stateMutex_);
105         CHECK_AND_RETURN_RET_LOG(currentState_ == LOOPBACK_STATE_RUNNING, true, "AudioLoopback not Running");
106         currentState_ = LOOPBACK_STATE_DESTROYING;
107         stateLock.unlock();
108         DestroyAudioLoopbackInner();
109         currentState_ = LOOPBACK_STATE_IDLE;
110     }
111     return true;
112 }
113 
InitStatus()114 void AudioLoopbackPrivate::InitStatus()
115 {
116     currentState_ = LOOPBACK_STATE_IDLE;
117 
118     rendererState_ = RENDERER_INVALID;
119     isRendererUsb_ = false;
120     rendererFastStatus_ = FASTSTATUS_NORMAL;
121 
122     capturerState_ = CAPTURER_INVALID;
123     isCapturerUsb_ = false;
124     capturerFastStatus_ = FASTSTATUS_NORMAL;
125 }
126 
GetStatus()127 AudioLoopbackStatus AudioLoopbackPrivate::GetStatus()
128 {
129     Trace trace("AudioLoopbackPrivate::GetStatus");
130     std::unique_lock<std::mutex> stateLock(stateMutex_);
131     AudioLoopbackStatus status = StateToStatus(currentState_);
132     if (status == LOOPBACK_UNAVAILABLE_SCENE || status == LOOPBACK_UNAVAILABLE_DEVICE) {
133         currentState_ = LOOPBACK_STATE_IDLE;
134     }
135     return status;
136 }
137 
StateToStatus(AudioLoopbackState state)138 AudioLoopbackStatus AudioLoopbackPrivate::StateToStatus(AudioLoopbackState state)
139 {
140     if (state == LOOPBACK_STATE_RUNNING) {
141         return LOOPBACK_AVAILABLE_RUNNING;
142     }
143     bool ret = CheckDeviceSupport();
144     if (!ret) {
145         return LOOPBACK_UNAVAILABLE_DEVICE;
146     }
147     if (state == LOOPBACK_STATE_DESTROYED || state == LOOPBACK_STATE_DESTROYING) {
148         return LOOPBACK_UNAVAILABLE_SCENE;
149     }
150     return LOOPBACK_AVAILABLE_IDLE;
151 }
152 
SetVolume(float volume)153 int32_t AudioLoopbackPrivate::SetVolume(float volume)
154 {
155     Trace trace("AudioLoopbackPrivate::SetVolume");
156     if (volume < 0.0 || volume > 1.0) {
157         AUDIO_ERR_LOG("SetVolume with invalid volume %{public}f", volume);
158         return ERR_INVALID_PARAM;
159     }
160     std::unique_lock<std::mutex> stateLock(stateMutex_);
161     karaokeParams_["Karaoke_volume"] = std::to_string(static_cast<int>(volume * VALUE_HUNDRED));
162     if (currentState_ == LOOPBACK_STATE_RUNNING) {
163         std::string parameters = "Karaoke_volume=" + karaokeParams_["Karaoke_volume"];
164         CHECK_AND_RETURN_RET_LOG(AudioPolicyManager::GetInstance().SetKaraokeParameters(parameters), ERROR,
165             "SetVolume failed");
166     }
167     return SUCCESS;
168 }
169 
SetReverbPreset(AudioLoopbackReverbPreset preset)170 bool AudioLoopbackPrivate::SetReverbPreset(AudioLoopbackReverbPreset preset)
171 {
172     std::unique_lock<std::mutex> stateLock(stateMutex_);
173     auto it = audioLoopbackReverbPresetMap.find(preset);
174     CHECK_AND_RETURN_RET_LOG(it != audioLoopbackReverbPresetMap.end(), false, "preset invalid");
175     currentReverbPreset_ = preset;
176     karaokeParams_["Karaoke_reverb_mode"] = it->second;
177     if (currentState_ == LOOPBACK_STATE_RUNNING) {
178         std::string parameters = "Karaoke_reverb_mode=" + karaokeParams_["Karaoke_reverb_mode"];
179         CHECK_AND_RETURN_RET_LOG(AudioPolicyManager::GetInstance().SetKaraokeParameters(parameters), false,
180             "SetReverbPreset failed");
181     }
182     return true;
183 }
184 
GetReverbPreset()185 AudioLoopbackReverbPreset AudioLoopbackPrivate::GetReverbPreset()
186 {
187     std::unique_lock<std::mutex> stateLock(stateMutex_);
188     return currentReverbPreset_;
189 }
190 
SetEqualizerPreset(AudioLoopbackEqualizerPreset preset)191 bool AudioLoopbackPrivate::SetEqualizerPreset(AudioLoopbackEqualizerPreset preset)
192 {
193     std::unique_lock<std::mutex> stateLock(stateMutex_);
194     auto it = audioLoopbackEqualizerPresetMap.find(preset);
195     CHECK_AND_RETURN_RET_LOG(it != audioLoopbackEqualizerPresetMap.end(), false, "preset invalid");
196     currentEqualizerPreset_ = preset;
197     karaokeParams_["Karaoke_eq_mode"] = it->second;
198     if (currentState_ == LOOPBACK_STATE_RUNNING) {
199         std::string parameters = "Karaoke_eq_mode=" + karaokeParams_["Karaoke_eq_mode"];
200         CHECK_AND_RETURN_RET_LOG(AudioPolicyManager::GetInstance().SetKaraokeParameters(parameters), false,
201             "SetEqualizerPreset failed");
202     }
203     return true;
204 }
205 
GetEqualizerPreset()206 AudioLoopbackEqualizerPreset AudioLoopbackPrivate::GetEqualizerPreset()
207 {
208     std::unique_lock<std::mutex> stateLock(stateMutex_);
209     return currentEqualizerPreset_;
210 }
211 
SetAudioLoopbackCallback(const std::shared_ptr<AudioLoopbackCallback> & callback)212 int32_t AudioLoopbackPrivate::SetAudioLoopbackCallback(const std::shared_ptr<AudioLoopbackCallback> &callback)
213 {
214     std::unique_lock<std::mutex> stateLock(stateMutex_);
215     statusCallback_ = callback;
216     return SUCCESS;
217 }
218 
RemoveAudioLoopbackCallback()219 int32_t AudioLoopbackPrivate::RemoveAudioLoopbackCallback()
220 {
221     std::unique_lock<std::mutex> stateLock(stateMutex_);
222     statusCallback_ = nullptr;
223     return SUCCESS;
224 }
225 
CreateAudioLoopback()226 void AudioLoopbackPrivate::CreateAudioLoopback()
227 {
228     Trace trace("AudioLoopbackPrivate::CreateAudioLoopback");
229     audioRenderer_ = AudioRenderer::CreateRenderer(rendererOptions_, appInfo_);
230     CHECK_AND_RETURN_LOG(audioRenderer_ != nullptr, "CreateRenderer failed");
231     CHECK_AND_RETURN_LOG(audioRenderer_->IsFastRenderer(), "CreateFastRenderer failed");
232     audioRenderer_->SetRendererWriteCallback(shared_from_this());
233     rendererFastStatus_ = FASTSTATUS_FAST;
234     audioCapturer_ = AudioCapturer::CreateCapturer(capturerOptions_, appInfo_);
235     CHECK_AND_RETURN_LOG(audioCapturer_ != nullptr, "CreateCapturer failed");
236     AudioCapturerInfo capturerInfo;
237     audioCapturer_->GetCapturerInfo(capturerInfo);
238     CHECK_AND_RETURN_LOG(capturerInfo.capturerFlags == STREAM_FLAG_FAST, "CreateFastCapturer failed");
239     audioCapturer_->SetCapturerReadCallback(shared_from_this());
240     InitializeCallbacks();
241     capturerFastStatus_ = FASTSTATUS_FAST;
242     CHECK_AND_RETURN_LOG(audioRenderer_->Start(), "audioRenderer Start failed");
243     rendererState_ = RENDERER_RUNNING;
244     CHECK_AND_RETURN_LOG(audioCapturer_->Start(), "audioCapturer Start failed");
245     capturerState_ = CAPTURER_RUNNING;
246 }
247 
DisableLoopback()248 void AudioLoopbackPrivate::DisableLoopback()
249 {
250     if (karaokeParams_["Karaoke_enable"] == "enable") {
251         karaokeParams_["Karaoke_enable"] = "disable";
252         std::string parameters = "Karaoke_enable=" + karaokeParams_["Karaoke_enable"];
253         CHECK_AND_RETURN_LOG(AudioPolicyManager::GetInstance().SetKaraokeParameters(parameters),
254             "DisableLoopback failed");
255     }
256 }
257 
DestroyAudioLoopbackInner()258 void AudioLoopbackPrivate::DestroyAudioLoopbackInner()
259 {
260     Trace trace("AudioLoopbackPrivate::DestroyAudioLoopbackInner");
261     DisableLoopback();
262     if (audioCapturer_) {
263         audioCapturer_->Stop();
264         audioCapturer_->Release();
265         audioCapturer_ = nullptr;
266     } else {
267         AUDIO_WARNING_LOG("audioCapturer is nullptr");
268     }
269     if (audioRenderer_) {
270         audioRenderer_->Stop();
271         audioRenderer_->Release();
272         audioRenderer_ = nullptr;
273     } else {
274         AUDIO_WARNING_LOG("audioRenderer is nullptr");
275     }
276 }
277 
DestroyAudioLoopback()278 void AudioLoopbackPrivate::DestroyAudioLoopback()
279 {
280     Trace trace("AudioLoopbackPrivate::DestroyAudioLoopback");
281     std::lock_guard<std::mutex> lock(loopbackMutex_);
282     DestroyAudioLoopbackInner();
283 }
284 
GenerateRendererConfig()285 AudioRendererOptions AudioLoopbackPrivate::GenerateRendererConfig()
286 {
287     AudioRendererOptions rendererOptions = {};
288     rendererOptions.streamInfo.samplingRate = AudioSamplingRate::SAMPLE_RATE_48000;
289     rendererOptions.streamInfo.encoding = AudioEncodingType::ENCODING_PCM;
290     rendererOptions.streamInfo.format = AudioSampleFormat::SAMPLE_S16LE;
291     rendererOptions.streamInfo.channels = AudioChannel::STEREO;
292     rendererOptions.rendererInfo.contentType = ContentType::CONTENT_TYPE_MUSIC;
293     rendererOptions.rendererInfo.streamUsage = StreamUsage::STREAM_USAGE_MUSIC;
294     rendererOptions.rendererInfo.rendererFlags = STREAM_FLAG_FAST;
295     rendererOptions.rendererInfo.isLoopback = true;
296     rendererOptions.rendererInfo.loopbackMode = mode_;
297     return rendererOptions;
298 }
299 
GenerateCapturerConfig()300 AudioCapturerOptions AudioLoopbackPrivate::GenerateCapturerConfig()
301 {
302     AudioCapturerOptions capturerOptions = {};
303     capturerOptions.streamInfo.samplingRate = AudioSamplingRate::SAMPLE_RATE_48000;
304     capturerOptions.streamInfo.encoding = AudioEncodingType::ENCODING_PCM;
305     capturerOptions.streamInfo.format = AudioSampleFormat::SAMPLE_S16LE;
306     capturerOptions.streamInfo.channels = AudioChannel::STEREO;
307     capturerOptions.capturerInfo.sourceType = SourceType::SOURCE_TYPE_MIC;
308     capturerOptions.capturerInfo.capturerFlags = STREAM_FLAG_FAST;
309     capturerOptions.capturerInfo.isLoopback = true;
310     capturerOptions.capturerInfo.loopbackMode = mode_;
311     return capturerOptions;
312 }
313 
IsAudioLoopbackSupported()314 bool AudioLoopbackPrivate::IsAudioLoopbackSupported()
315 {
316     Trace trace("AudioLoopbackPrivate::IsAudioLoopbackSupported");
317     return AudioPolicyManager::GetInstance().IsAudioLoopbackSupported(mode_);
318 }
319 
CheckDeviceSupport()320 bool AudioLoopbackPrivate::CheckDeviceSupport()
321 {
322     isRendererUsb_ = AudioPolicyManager::GetInstance().GetActiveOutputDevice() == DEVICE_TYPE_USB_HEADSET;
323     isCapturerUsb_ = AudioPolicyManager::GetInstance().GetActiveInputDevice() == DEVICE_TYPE_USB_HEADSET;
324     return isRendererUsb_ && isCapturerUsb_;
325 }
326 
EnableLoopback()327 bool AudioLoopbackPrivate::EnableLoopback()
328 {
329     Trace trace("AudioLoopbackPrivate::EnableLoopback");
330     karaokeParams_["Karaoke_enable"] = "enable";
331     std::string parameters = "";
332     for (auto &param : karaokeParams_) {
333         parameters = param.first + "=" + param.second + ";";
334         CHECK_AND_RETURN_RET_LOG(AudioPolicyManager::GetInstance().SetKaraokeParameters(parameters), false,
335             "SetKaraokeParameters failed");
336     }
337     return true;
338 }
339 
OnReadData(size_t length)340 void AudioLoopbackPrivate::OnReadData(size_t length)
341 {
342     CHECK_AND_RETURN_LOG(audioCapturer_ != nullptr, "audioCapturer is nullptr");
343     BufferDesc bufDesc;
344     int32_t ret = audioCapturer_->GetBufferDesc(bufDesc);
345     CHECK_AND_RETURN_LOG(ret == SUCCESS, "get bufDesc failed, bufLength=%{public}zu, dataLength=%{public}zu",
346         bufDesc.bufLength, bufDesc.dataLength);
347 }
348 
OnWriteData(size_t length)349 void AudioLoopbackPrivate::OnWriteData(size_t length)
350 {
351     CHECK_AND_RETURN_LOG(audioRenderer_ != nullptr, "audioRenderer is nullptr");
352     BufferDesc bufDesc;
353     audioRenderer_->GetBufferDesc(bufDesc);
354     memset_s((void*)bufDesc.buffer, bufDesc.bufLength, 0, bufDesc.bufLength);
355     audioRenderer_->Enqueue(bufDesc);
356 }
357 
RendererCallbackImpl(AudioLoopbackPrivate & parent)358 AudioLoopbackPrivate::RendererCallbackImpl::RendererCallbackImpl(AudioLoopbackPrivate &parent)
359     : parent_(parent) {}
360 
OnStateChange(const RendererState state,const StateChangeCmdType cmdType)361 void AudioLoopbackPrivate::RendererCallbackImpl::OnStateChange(
362     const RendererState state, const StateChangeCmdType __attribute__((unused)) cmdType)
363 {
364     parent_.rendererState_ = state;
365     parent_.UpdateStatus();
366 }
367 
OnOutputDeviceChange(const AudioDeviceDescriptor & deviceInfo,const AudioStreamDeviceChangeReason reason)368 void AudioLoopbackPrivate::RendererCallbackImpl::OnOutputDeviceChange(const AudioDeviceDescriptor &deviceInfo,
369     const AudioStreamDeviceChangeReason __attribute__((unused)) reason)
370 {
371     parent_.isRendererUsb_ = (deviceInfo.deviceType_ == DEVICE_TYPE_USB_HEADSET);
372     parent_.UpdateStatus();
373 }
374 
OnFastStatusChange(FastStatus status)375 void AudioLoopbackPrivate::RendererCallbackImpl::OnFastStatusChange(FastStatus status)
376 {
377     parent_.rendererFastStatus_ = status;
378     parent_.UpdateStatus();
379 }
380 
CapturerCallbackImpl(AudioLoopbackPrivate & parent)381 AudioLoopbackPrivate::CapturerCallbackImpl::CapturerCallbackImpl(AudioLoopbackPrivate &parent)
382     : parent_(parent) {}
383 
OnStateChange(const CapturerState state)384 void AudioLoopbackPrivate::CapturerCallbackImpl::OnStateChange(const CapturerState state)
385 {
386     parent_.capturerState_ = state;
387     parent_.UpdateStatus();
388 }
389 
OnStateChange(const AudioDeviceDescriptor & deviceInfo)390 void AudioLoopbackPrivate::CapturerCallbackImpl::OnStateChange(const AudioDeviceDescriptor &deviceInfo)
391 {
392     parent_.isCapturerUsb_ = (deviceInfo.deviceType_ == DEVICE_TYPE_USB_HEADSET);
393     parent_.UpdateStatus();
394 }
395 
OnFastStatusChange(FastStatus status)396 void AudioLoopbackPrivate::CapturerCallbackImpl::OnFastStatusChange(FastStatus status)
397 {
398     parent_.capturerFastStatus_ = status;
399     parent_.UpdateStatus();
400 }
401 
InitializeCallbacks()402 void AudioLoopbackPrivate::InitializeCallbacks()
403 {
404     auto rendererCallback = std::make_shared<RendererCallbackImpl>(*this);
405     audioRenderer_->SetRendererCallback(rendererCallback);
406     audioRenderer_->RegisterOutputDeviceChangeWithInfoCallback(rendererCallback);
407     audioRenderer_->SetFastStatusChangeCallback(rendererCallback);
408 
409     auto capturerCallback = std::make_shared<CapturerCallbackImpl>(*this);
410     audioCapturer_->SetCapturerCallback(capturerCallback);
411     audioCapturer_->SetAudioCapturerDeviceChangeCallback(capturerCallback);
412     audioCapturer_->SetFastStatusChangeCallback(capturerCallback);
413 }
414 
GetCurrentState()415 AudioLoopbackState AudioLoopbackPrivate::GetCurrentState()
416 {
417     std::unique_lock<std::mutex> stateLock(stateMutex_);
418     return currentState_;
419 }
420 
UpdateStatus()421 void AudioLoopbackPrivate::UpdateStatus()
422 {
423     Trace trace("AudioLoopbackPrivate::UpdateStatus");
424     std::unique_lock<std::mutex> stateLock(stateMutex_);
425     CHECK_AND_RETURN(currentState_ == LOOPBACK_STATE_RUNNING || currentState_ == LOOPBACK_STATE_PREPARED);
426     AudioLoopbackState oldState = currentState_;
427     AudioLoopbackState newState = currentState_;
428     const bool isDeviceValid = isRendererUsb_.load() && isCapturerUsb_.load();
429     const bool isStateRunning = (rendererState_.load() == RENDERER_RUNNING) &&
430         (capturerState_.load() == CAPTURER_RUNNING);
431     const bool isFastValid = (rendererFastStatus_.load() == FASTSTATUS_FAST) &&
432         (capturerFastStatus_.load() == FASTSTATUS_FAST);
433     newState = (isDeviceValid && isStateRunning && isFastValid) ? LOOPBACK_STATE_RUNNING : LOOPBACK_STATE_DESTROYED;
434 
435     if (newState == LOOPBACK_STATE_RUNNING) {
436         newState = EnableLoopback() ? LOOPBACK_STATE_RUNNING : LOOPBACK_STATE_DESTROYED;
437     }
438     if (newState != oldState) {
439         AUDIO_INFO_LOG("UpdateState: %{public}d -> %{public}d", oldState, newState);
440         if (newState == LOOPBACK_STATE_DESTROYED) {
441             currentState_ = LOOPBACK_STATE_DESTROYING;
442             auto self = shared_from_this();
443             std::thread([self] {
444                 self->DestroyAudioLoopback();
445             }).detach();
446         }
447         currentState_ = newState;
448         if (statusCallback_) {
449             statusCallback_->OnStatusChange(StateToStatus(currentState_));
450         }
451     }
452 }
453 }  // namespace AudioStandard
454 }  // namespace OHOS