• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 
16 #ifndef LOG_TAG
17 #define LOG_TAG "AudioVolume"
18 #endif
19 
20 #include "audio_volume.h"
21 #include "audio_volume_c.h"
22 #include "audio_common_log.h"
23 #include "audio_utils.h"
24 #include "audio_stream_info.h"
25 #include "media_monitor_manager.h"
26 #include "event_bean.h"
27 
28 namespace OHOS {
29 namespace AudioStandard {
30 static const std::unordered_map<std::string, AudioStreamType> STREAM_TYPE_STRING_ENUM_MAP = {
31     {"voice_call", STREAM_VOICE_CALL},
32     {"voice_call_assistant", STREAM_VOICE_CALL_ASSISTANT},
33     {"music", STREAM_MUSIC},
34     {"ring", STREAM_RING},
35     {"media", STREAM_MEDIA},
36     {"voice_assistant", STREAM_VOICE_ASSISTANT},
37     {"system", STREAM_SYSTEM},
38     {"alarm", STREAM_ALARM},
39     {"notification", STREAM_NOTIFICATION},
40     {"bluetooth_sco", STREAM_BLUETOOTH_SCO},
41     {"enforced_audible", STREAM_ENFORCED_AUDIBLE},
42     {"dtmf", STREAM_DTMF},
43     {"tts", STREAM_TTS},
44     {"accessibility", STREAM_ACCESSIBILITY},
45     {"recording", STREAM_RECORDING},
46     {"movie", STREAM_MOVIE},
47     {"game", STREAM_GAME},
48     {"speech", STREAM_SPEECH},
49     {"system_enforced", STREAM_SYSTEM_ENFORCED},
50     {"ultrasonic", STREAM_ULTRASONIC},
51     {"wakeup", STREAM_WAKEUP},
52     {"voice_message", STREAM_VOICE_MESSAGE},
53     {"navigation", STREAM_NAVIGATION}
54 };
55 
GetInstance()56 AudioVolume *AudioVolume::GetInstance()
57 {
58     static AudioVolume instance;
59     return &instance;
60 }
61 
AudioVolume()62 AudioVolume::AudioVolume()
63 {
64     AUDIO_INFO_LOG("AudioVolume construct");
65 }
66 
~AudioVolume()67 AudioVolume::~AudioVolume()
68 {
69     streamVolume_.clear();
70     systemVolume_.clear();
71     historyVolume_.clear();
72     monitorVolume_.clear();
73 }
74 
GetVolume(uint32_t sessionId,int32_t volumeType,const std::string & deviceClass)75 float AudioVolume::GetVolume(uint32_t sessionId, int32_t volumeType, const std::string &deviceClass)
76 {
77     Trace trace("AudioVolume::GetVolume sessionId:" + std::to_string(sessionId));
78     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
79     float volumeStream = 1.0f;
80     auto it = streamVolume_.find(sessionId);
81     if (it != streamVolume_.end()) {
82         volumeStream =
83             it->second.isMuted_ ? 0.0f : it->second.volume_ * it->second.duckFactor_ * it->second.lowPowerFactor_;
84         AUDIO_DEBUG_LOG("stream volume, sessionId:%{public}u, volume:%{public}f, duck:%{public}f, lowPower:%{public}f,"
85             " isMuted:%{public}d, streamVolumeSize:%{public}zu",
86             sessionId, it->second.volume_, it->second.duckFactor_, it->second.lowPowerFactor_, it->second.isMuted_,
87             streamVolume_.size());
88     } else {
89         AUDIO_ERR_LOG("stream volume not exist, sessionId:%{public}u, streamVolumeSize:%{public}zu",
90             sessionId, streamVolume_.size());
91     }
92 
93     std::shared_lock<std::shared_mutex> lockSystem(systemMutex_);
94     int32_t volumeLevel = 0;
95     float volumeSystem = 1.0f;
96     std::string key = std::to_string(volumeType) + deviceClass;
97     auto itSV = systemVolume_.find(key);
98     if (itSV != systemVolume_.end()) {
99         volumeLevel = itSV->second.volumeLevel_;
100         volumeSystem = itSV->second.isMuted_ ? 0.0f : itSV->second.volume_;
101         AUDIO_DEBUG_LOG("system volume, volumeType:%{public}d, deviceClass:%{public}s,"
102             " volume:%{public}f, isMuted:%{public}d, systemVolumeSize:%{public}zu",
103             volumeType, deviceClass.c_str(), itSV->second.volume_, itSV->second.isMuted_, systemVolume_.size());
104     } else {
105         AUDIO_ERR_LOG("system volume not exist, volumeType:%{public}d, deviceClass:%{public}s,"
106             " systemVolumeSize:%{public}zu", volumeType, deviceClass.c_str(), systemVolume_.size());
107     }
108     float volumeFloat = volumeStream * volumeSystem;
109     if (monitorVolume_.find(sessionId) != monitorVolume_.end()) {
110         monitorVolume_[sessionId] = {volumeFloat, volumeLevel};
111     }
112     return volumeFloat;
113 }
114 
GetHistoryVolume(uint32_t sessionId)115 float AudioVolume::GetHistoryVolume(uint32_t sessionId)
116 {
117     Trace trace("AudioVolume::GetHistoryVolume sessionId:" + std::to_string(sessionId));
118     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
119     auto it = historyVolume_.find(sessionId);
120     if (it != historyVolume_.end()) {
121         return it->second;
122     }
123     return 0.0f;
124 }
125 
SetHistoryVolume(uint32_t sessionId,float volume)126 void AudioVolume::SetHistoryVolume(uint32_t sessionId, float volume)
127 {
128     AUDIO_INFO_LOG("history volume, sessionId:%{public}u, volume:%{public}f", sessionId, volume);
129     Trace trace("AudioVolume::SetHistoryVolume sessionId:" + std::to_string(sessionId));
130     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
131     auto it = historyVolume_.find(sessionId);
132     if (it != historyVolume_.end()) {
133         it->second = volume;
134     }
135 }
136 
AddStreamVolume(uint32_t sessionId,int32_t streamType,int32_t streamUsage,int32_t uid,int32_t pid)137 void AudioVolume::AddStreamVolume(uint32_t sessionId, int32_t streamType, int32_t streamUsage,
138     int32_t uid, int32_t pid)
139 {
140     AUDIO_INFO_LOG("stream volume, sessionId:%{public}u", sessionId);
141     std::unique_lock<std::shared_mutex> lock(volumeMutex_);
142     auto it = streamVolume_.find(sessionId);
143     if (it == streamVolume_.end()) {
144         streamVolume_.emplace(sessionId, StreamVolume(sessionId, streamType, streamUsage, uid, pid));
145         historyVolume_.emplace(sessionId, 0.0f);
146         monitorVolume_.emplace(sessionId, std::make_pair(0.0f, 0));
147     } else {
148         AUDIO_ERR_LOG("stream volume already exist, sessionId:%{public}u", sessionId);
149     }
150 }
151 
RemoveStreamVolume(uint32_t sessionId)152 void AudioVolume::RemoveStreamVolume(uint32_t sessionId)
153 {
154     AUDIO_INFO_LOG("stream volume, sessionId:%{public}u", sessionId);
155     std::unique_lock<std::shared_mutex> lock(volumeMutex_);
156     auto it = streamVolume_.find(sessionId);
157     if (it != streamVolume_.end()) {
158         streamVolume_.erase(sessionId);
159     } else {
160         AUDIO_ERR_LOG("stream volume already delete, sessionId:%{public}u", sessionId);
161     }
162     auto itHistory = historyVolume_.find(sessionId);
163     if (itHistory != historyVolume_.end()) {
164         historyVolume_.erase(sessionId);
165     }
166     auto itMonitor = monitorVolume_.find(sessionId);
167     if (itMonitor != monitorVolume_.end()) {
168         monitorVolume_.erase(sessionId);
169     }
170 }
171 
SetStreamVolume(uint32_t sessionId,float volume)172 void AudioVolume::SetStreamVolume(uint32_t sessionId, float volume)
173 {
174     AUDIO_INFO_LOG("stream volume, sessionId:%{public}u, volume:%{public}f", sessionId, volume);
175     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
176     auto it = streamVolume_.find(sessionId);
177     if (it != streamVolume_.end()) {
178         it->second.volume_ = volume;
179     } else {
180         AUDIO_ERR_LOG("stream volume not exist, sessionId:%{public}u", sessionId);
181     }
182 }
183 
SetStreamVolumeDuckFactor(uint32_t sessionId,float duckFactor)184 void AudioVolume::SetStreamVolumeDuckFactor(uint32_t sessionId, float duckFactor)
185 {
186     AUDIO_INFO_LOG("stream volume, sessionId:%{public}u, duckFactor:%{public}f", sessionId, duckFactor);
187     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
188     auto it = streamVolume_.find(sessionId);
189     if (it != streamVolume_.end()) {
190         it->second.duckFactor_ = duckFactor;
191     } else {
192         AUDIO_ERR_LOG("stream volume not exist, sessionId:%{public}u", sessionId);
193     }
194 }
195 
SetStreamVolumeLowPowerFactor(uint32_t sessionId,float lowPowerFactor)196 void AudioVolume::SetStreamVolumeLowPowerFactor(uint32_t sessionId, float lowPowerFactor)
197 {
198     AUDIO_INFO_LOG("stream volume, sessionId:%{public}u, lowPowerFactor:%{public}f", sessionId, lowPowerFactor);
199     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
200     auto it = streamVolume_.find(sessionId);
201     if (it != streamVolume_.end()) {
202         it->second.lowPowerFactor_ = lowPowerFactor;
203     } else {
204         AUDIO_ERR_LOG("stream volume not exist, sessionId:%{public}u", sessionId);
205     }
206 }
207 
SetStreamVolumeMute(uint32_t sessionId,bool isMuted)208 void AudioVolume::SetStreamVolumeMute(uint32_t sessionId, bool isMuted)
209 {
210     AUDIO_INFO_LOG("stream volume, sessionId:%{public}u, isMuted:%{public}d", sessionId, isMuted);
211     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
212     auto it = streamVolume_.find(sessionId);
213     if (it != streamVolume_.end()) {
214         it->second.isMuted_ = isMuted;
215     }
216 }
217 
SetStreamVolumeFade(uint32_t sessionId,float fadeBegin,float fadeEnd)218 void AudioVolume::SetStreamVolumeFade(uint32_t sessionId, float fadeBegin, float fadeEnd)
219 {
220     AUDIO_INFO_LOG("stream volume, sessionId:%{public}u, fadeBegin:%{public}f, fadeEnd:%{public}f",
221         sessionId, fadeBegin, fadeEnd);
222     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
223     auto it = streamVolume_.find(sessionId);
224     if (it != streamVolume_.end()) {
225         it->second.fadeBegin_ = fadeBegin;
226         it->second.fadeEnd_ = fadeEnd;
227     } else {
228         AUDIO_ERR_LOG("stream volume not exist, sessionId:%{public}u", sessionId);
229     }
230 }
231 
GetStreamVolumeFade(uint32_t sessionId)232 std::pair<float, float> AudioVolume::GetStreamVolumeFade(uint32_t sessionId)
233 {
234     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
235     auto it = streamVolume_.find(sessionId);
236     if (it != streamVolume_.end()) {
237         return {it->second.fadeBegin_, it->second.fadeEnd_};
238     } else {
239         AUDIO_ERR_LOG("stream volume not exist, sessionId:%{public}u", sessionId);
240     }
241     return {1.0f, 1.0f};
242 }
243 
SetSystemVolume(SystemVolume & systemVolume)244 void AudioVolume::SetSystemVolume(SystemVolume &systemVolume)
245 {
246     auto volumeType = systemVolume.GetVolumeType();
247     auto deviceClass = systemVolume.GetDeviceClass();
248     std::string key = std::to_string(volumeType) + deviceClass;
249     bool haveSystemVolume = true;
250     {
251         std::shared_lock<std::shared_mutex> lock(systemMutex_);
252         auto it = systemVolume_.find(key);
253         if (it != systemVolume_.end()) {
254             it->second.volume_ = systemVolume.volume_;
255             it->second.volumeLevel_ = systemVolume.volumeLevel_;
256             it->second.isMuted_ = systemVolume.isMuted_;
257         } else {
258             haveSystemVolume = false;
259         }
260     }
261     if (!haveSystemVolume) {
262         std::unique_lock<std::shared_mutex> lock(systemMutex_);
263         systemVolume_.emplace(key, systemVolume);
264     }
265     AUDIO_INFO_LOG("system volume, volumeType:%{public}d, deviceClass:%{public}s,"
266         " volume:%{public}f, volumeLevel:%{public}d, isMuted:%{public}d, systemVolumeSize:%{public}zu",
267         volumeType, deviceClass.c_str(), systemVolume.volume_, systemVolume.volumeLevel_, systemVolume.isMuted_,
268         systemVolume_.size());
269 }
270 
SetSystemVolume(int32_t volumeType,const std::string & deviceClass,float volume,int32_t volumeLevel)271 void AudioVolume::SetSystemVolume(int32_t volumeType, const std::string &deviceClass, float volume, int32_t volumeLevel)
272 {
273     std::string key = std::to_string(volumeType) + deviceClass;
274     bool haveSystemVolume = true;
275     {
276         std::shared_lock<std::shared_mutex> lock(systemMutex_);
277         auto it = systemVolume_.find(key);
278         if (it != systemVolume_.end()) {
279             it->second.volume_ = volume;
280             it->second.volumeLevel_ = volumeLevel;
281         } else {
282             haveSystemVolume = false;
283         }
284     }
285     if (!haveSystemVolume) {
286         std::unique_lock<std::shared_mutex> lock(systemMutex_);
287         SystemVolume systemVolume(volumeType, deviceClass, volume, volumeLevel, false);
288         systemVolume_.emplace(key, systemVolume);
289     }
290     AUDIO_INFO_LOG("system volume, volumeType:%{public}d, deviceClass:%{public}s,"
291         " volume:%{public}f, volumeLevel:%{public}d, systemVolumeSize:%{public}zu",
292         volumeType, deviceClass.c_str(), volume, volumeLevel, systemVolume_.size());
293 }
294 
SetSystemVolumeMute(int32_t volumeType,const std::string & deviceClass,bool isMuted)295 void AudioVolume::SetSystemVolumeMute(int32_t volumeType, const std::string &deviceClass, bool isMuted)
296 {
297     AUDIO_INFO_LOG("system volume, volumeType:%{public}d, deviceClass:%{public}s, isMuted:%{public}d",
298         volumeType, deviceClass.c_str(), isMuted);
299     std::string key = std::to_string(volumeType) + deviceClass;
300     bool haveSystemVolume = true;
301     {
302         std::shared_lock<std::shared_mutex> lock(systemMutex_);
303         auto it = systemVolume_.find(key);
304         if (it != systemVolume_.end()) {
305             it->second.isMuted_ = isMuted;
306         } else {
307             haveSystemVolume = false;
308         }
309     }
310     if (!haveSystemVolume) {
311         std::unique_lock<std::shared_mutex> lock(systemMutex_);
312         SystemVolume systemVolume(volumeType, deviceClass, 0.0f, 0, isMuted);
313         systemVolume_.emplace(key, systemVolume);
314     }
315 }
316 
ConvertStreamTypeStrToInt(const std::string & streamType)317 int32_t AudioVolume::ConvertStreamTypeStrToInt(const std::string &streamType)
318 {
319     AudioStreamType stream = STREAM_MUSIC;
320     if (STREAM_TYPE_STRING_ENUM_MAP.find(streamType) != STREAM_TYPE_STRING_ENUM_MAP.end()) {
321         stream = STREAM_TYPE_STRING_ENUM_MAP.at(streamType);
322     } else {
323         AUDIO_WARNING_LOG("Invalid stream type [%{public}s]. Use default type", streamType.c_str());
324     }
325     return stream;
326 }
327 
IsSameVolume(float x,float y)328 bool AudioVolume::IsSameVolume(float x, float y)
329 {
330     return (std::abs((x) - (y)) <= std::abs(FLOAT_EPS));
331 }
332 
Dump(std::string & dumpString)333 void AudioVolume::Dump(std::string &dumpString)
334 {
335     AUDIO_INFO_LOG("AudioVolume dump begin");
336     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
337     // dump system volume
338     std::vector<SystemVolume> systemVolumeList;
339     for (auto &systemVolume : systemVolume_) {
340         systemVolumeList.push_back(systemVolume.second);
341     }
342     std::sort(systemVolumeList.begin(), systemVolumeList.end(), [](SystemVolume &a, SystemVolume &b) {
343         return a.GetVolumeType() < b.GetVolumeType();
344     });
345     AppendFormat(dumpString, "\n  - audio system volume size: %zu\n", systemVolumeList.size());
346     for (auto &systemVolume : systemVolumeList) {
347         AppendFormat(dumpString, "  streamtype: %d ", systemVolume.GetVolumeType());
348         AppendFormat(dumpString, "  isMute: %s ", (systemVolume.isMuted_ ? "true" : "false"));
349         AppendFormat(dumpString, "  volFloat: %f ", systemVolume.volume_);
350         AppendFormat(dumpString, "  volInt: %d ", systemVolume.volumeLevel_);
351         AppendFormat(dumpString, "  device class: %s \n", systemVolume.GetDeviceClass().c_str());
352     }
353 
354     // dump stream volume
355     std::vector<StreamVolume> streamVolumeList;
356     for (auto &streamVolume : streamVolume_) {
357         streamVolumeList.push_back(streamVolume.second);
358     }
359     std::sort(streamVolumeList.begin(), streamVolumeList.end(), [](StreamVolume &a, StreamVolume &b) {
360         return a.GetSessionId() < b.GetSessionId();
361     });
362     AppendFormat(dumpString, "\n  - audio stream volume size: %zu, his volume size: %zu, mon volume size: %zu\n",
363         streamVolumeList.size(), historyVolume_.size(), monitorVolume_.size());
364     for (auto &streamVolume : streamVolumeList) {
365         auto monVol = monitorVolume_.find(streamVolume.GetSessionId());
366         AppendFormat(dumpString, "  sessionId: %u ", streamVolume.GetSessionId());
367         AppendFormat(dumpString, "  streamType: %d ", streamVolume.GetStreamType());
368         AppendFormat(dumpString, "  streamUsage: %d ", streamVolume.GetStreamUsage());
369         AppendFormat(dumpString, "  appUid: %d ", streamVolume.GetAppUid());
370         AppendFormat(dumpString, "  appPid: %d ", streamVolume.GetAppPid());
371         AppendFormat(dumpString, "  volume: %f ", monVol != monitorVolume_.end() ? monVol->second.first : 0.0f);
372         AppendFormat(dumpString, "  volumeLevel: %d ",  monVol != monitorVolume_.end() ? monVol->second.second : 0);
373         AppendFormat(dumpString, "  volFactor: %f ", streamVolume.volume_);
374         AppendFormat(dumpString, "  duckFactor: %f ", streamVolume.duckFactor_);
375         AppendFormat(dumpString, "  powerFactor: %f ", streamVolume.lowPowerFactor_);
376         AppendFormat(dumpString, "  fadeBegin: %f ", streamVolume.fadeBegin_);
377         AppendFormat(dumpString, "  fadeEnd: %f \n", streamVolume.fadeEnd_);
378     }
379 }
380 
Monitor(uint32_t sessionId,bool isOutput)381 void AudioVolume::Monitor(uint32_t sessionId, bool isOutput)
382 {
383     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
384     auto streamVolume = streamVolume_.find(sessionId);
385     if (streamVolume != streamVolume_.end()) {
386         auto monVol = monitorVolume_.find(sessionId);
387         std::shared_ptr<Media::MediaMonitor::EventBean> bean = std::make_shared<Media::MediaMonitor::EventBean>(
388             Media::MediaMonitor::AUDIO, Media::MediaMonitor::VOLUME_CHANGE,
389             Media::MediaMonitor::BEHAVIOR_EVENT);
390         bean->Add("ISOUTPUT", isOutput ? 1 : 0);
391         bean->Add("STREAMID", static_cast<int32_t>(sessionId));
392         bean->Add("APP_UID", streamVolume->second.GetAppUid());
393         bean->Add("APP_PID", streamVolume->second.GetAppPid());
394         bean->Add("STREAMTYPE", streamVolume->second.GetStreamType());
395         bean->Add("STREAM_TYPE", streamVolume->second.GetStreamUsage());
396         bean->Add("VOLUME", monVol != monitorVolume_.end() ? monVol->second.first : 0.0f);
397         bean->Add("SYSVOLUME", monVol != monitorVolume_.end() ? monVol->second.second : 0);
398         bean->Add("VOLUMEFACTOR", streamVolume->second.volume_);
399         bean->Add("POWERVOLUMEFACTOR", streamVolume->second.lowPowerFactor_);
400         Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
401     } else {
402         AUDIO_ERR_LOG("stream volume not exist, sessionId:%{public}u", sessionId);
403     }
404 }
405 } // namespace AudioStandard
406 } // namespace OHOS
407 
408 #ifdef __cplusplus
409 extern "C" {
410 #endif
411 using namespace OHOS::AudioStandard;
412 
GetCurVolume(uint32_t sessionId,const char * streamType,const char * deviceClass)413 float GetCurVolume(uint32_t sessionId, const char *streamType, const char *deviceClass)
414 {
415     CHECK_AND_RETURN_RET_LOG(streamType != nullptr, 1.0f, "streamType is nullptr");
416     CHECK_AND_RETURN_RET_LOG(deviceClass != nullptr, 1.0f, "deviceClass is nullptr");
417     std::string tmpStreamType = streamType;
418     // Set voice call assistant stream type to full volume
419     if (tmpStreamType == "voice_call_assistant") {
420         return 1.0f;
421     }
422     int32_t stream = AudioVolume::GetInstance()->ConvertStreamTypeStrToInt(streamType);
423     AudioStreamType volumeType = VolumeUtils::GetVolumeTypeFromStreamType(static_cast<AudioStreamType>(stream));
424     return AudioVolume::GetInstance()->GetVolume(sessionId, volumeType, deviceClass);
425 }
426 
GetPreVolume(uint32_t sessionId)427 float GetPreVolume(uint32_t sessionId)
428 {
429     return AudioVolume::GetInstance()->GetHistoryVolume(sessionId);
430 }
431 
SetPreVolume(uint32_t sessionId,float volume)432 void SetPreVolume(uint32_t sessionId, float volume)
433 {
434     AudioVolume::GetInstance()->SetHistoryVolume(sessionId, volume);
435 }
436 
GetStreamVolumeFade(uint32_t sessionId,float * fadeBegin,float * fadeEnd)437 void GetStreamVolumeFade(uint32_t sessionId, float *fadeBegin, float *fadeEnd)
438 {
439     auto fade = AudioVolume::GetInstance()->GetStreamVolumeFade(sessionId);
440     *fadeBegin = fade.first;
441     *fadeEnd = fade.second;
442 }
443 
SetStreamVolumeFade(uint32_t sessionId,float fadeBegin,float fadeEnd)444 void SetStreamVolumeFade(uint32_t sessionId, float fadeBegin, float fadeEnd)
445 {
446     AudioVolume::GetInstance()->SetStreamVolumeFade(sessionId, fadeBegin, fadeEnd);
447 }
448 
IsSameVolume(float x,float y)449 bool IsSameVolume(float x, float y)
450 {
451     return AudioVolume::GetInstance()->IsSameVolume(x, y);
452 }
453 
MonitorVolume(uint32_t sessionId,bool isOutput)454 void MonitorVolume(uint32_t sessionId, bool isOutput)
455 {
456     AudioVolume::GetInstance()->Monitor(sessionId, isOutput);
457 }
458 #ifdef __cplusplus
459 }
460 #endif