• 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 
56 uint64_t DURATION_TIME_DEFAULT = 40;
57 uint64_t DURATION_TIME_SHORT = 10;
58 
GetInstance()59 AudioVolume *AudioVolume::GetInstance()
60 {
61     static AudioVolume instance;
62     return &instance;
63 }
64 
AudioVolume()65 AudioVolume::AudioVolume()
66 {
67     AUDIO_INFO_LOG("AudioVolume construct");
68 }
69 
~AudioVolume()70 AudioVolume::~AudioVolume()
71 {
72     streamVolume_.clear();
73     systemVolume_.clear();
74     historyVolume_.clear();
75     monitorVolume_.clear();
76 }
77 
GetVolume(uint32_t sessionId,int32_t volumeType,const std::string & deviceClass)78 float AudioVolume::GetVolume(uint32_t sessionId, int32_t volumeType, const std::string &deviceClass)
79 {
80     Trace trace("AudioVolume::GetVolume sessionId:" + std::to_string(sessionId));
81     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
82     float volumeStream = 1.0f;
83     auto it = streamVolume_.find(sessionId);
84     if (it != streamVolume_.end()) {
85         volumeStream =
86             it->second.isMuted_ ? 0.0f : it->second.volume_ * it->second.duckFactor_ * it->second.lowPowerFactor_;
87         AUDIO_DEBUG_LOG("stream volume, sessionId:%{public}u, volume:%{public}f, duck:%{public}f, lowPower:%{public}f,"
88             " isMuted:%{public}d, streamVolumeSize:%{public}zu",
89             sessionId, it->second.volume_, it->second.duckFactor_, it->second.lowPowerFactor_, it->second.isMuted_,
90             streamVolume_.size());
91     } else {
92         AUDIO_ERR_LOG("stream volume not exist, sessionId:%{public}u, streamVolumeSize:%{public}zu",
93             sessionId, streamVolume_.size());
94     }
95 
96     std::shared_lock<std::shared_mutex> lockSystem(systemMutex_);
97     int32_t volumeLevel = 0;
98     float volumeSystem = 1.0f;
99     std::string key = std::to_string(volumeType) + deviceClass;
100     auto itSV = systemVolume_.find(key);
101     if (itSV != systemVolume_.end()) {
102         volumeLevel = itSV->second.volumeLevel_;
103         volumeSystem = itSV->second.isMuted_ ? 0.0f : itSV->second.volume_;
104         AUDIO_DEBUG_LOG("system volume, volumeType:%{public}d, deviceClass:%{public}s,"
105             " volume:%{public}f, isMuted:%{public}d, systemVolumeSize:%{public}zu",
106             volumeType, deviceClass.c_str(), itSV->second.volume_, itSV->second.isMuted_, systemVolume_.size());
107     } else {
108         AUDIO_ERR_LOG("system volume not exist, volumeType:%{public}d, deviceClass:%{public}s,"
109             " systemVolumeSize:%{public}zu", volumeType, deviceClass.c_str(), systemVolume_.size());
110     }
111     float volumeFloat = volumeStream * volumeSystem;
112     if (monitorVolume_.find(sessionId) != monitorVolume_.end()) {
113         if (monitorVolume_[sessionId].first != volumeFloat) {
114             AUDIO_INFO_LOG("volume, sessionId:%{public}u, volume:%{public}f, volumeType:%{public}d,"
115                 " deviceClass:%{public}s, stream volume:%{public}f, system volume:%{public}f",
116                 sessionId, volumeFloat, volumeType, deviceClass.c_str(), volumeStream, volumeSystem);
117         }
118         monitorVolume_[sessionId] = {volumeFloat, volumeLevel};
119     }
120     Trace traceVolume("Volume, sessionId:" + std::to_string(sessionId) + ", volume:" + std::to_string(volumeFloat) +
121         ", stream volume:" + std::to_string(volumeStream) + ", system volume:" + std::to_string(volumeSystem));
122     return volumeFloat;
123 }
124 
GetStreamVolume(uint32_t sessionId)125 float AudioVolume::GetStreamVolume(uint32_t sessionId)
126 {
127     Trace trace("AudioVolume::GetStreamVolume sessionId:" + std::to_string(sessionId));
128     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
129     float volumeStream = 1.0f;
130     auto it = streamVolume_.find(sessionId);
131     if (it != streamVolume_.end()) {
132         volumeStream =
133             it->second.isMuted_ ? 0.0f : it->second.volume_ * it->second.duckFactor_ * it->second.lowPowerFactor_;
134         AUDIO_DEBUG_LOG("stream volume, sessionId:%{public}u, volume:%{public}f, duck:%{public}f, lowPower:%{public}f,"
135             " isMuted:%{public}d, streamVolumeSize:%{public}zu",
136             sessionId, it->second.volume_, it->second.duckFactor_, it->second.lowPowerFactor_, it->second.isMuted_,
137             streamVolume_.size());
138     } else {
139         AUDIO_ERR_LOG("stream volume not exist, sessionId:%{public}u, streamVolumeSize:%{public}zu",
140             sessionId, streamVolume_.size());
141     }
142     if (monitorVolume_.find(sessionId) != monitorVolume_.end()) {
143         if (monitorVolume_[sessionId].first != volumeStream) {
144             AUDIO_INFO_LOG("volume, sessionId:%{public}u, stream volume:%{public}f", sessionId, volumeStream);
145         }
146         monitorVolume_[sessionId] = {volumeStream, 15}; // 15 level only stream volume
147     }
148     Trace traceVolume("Volume, sessionId:" + std::to_string(sessionId) +
149         ", stream volume:" + std::to_string(volumeStream));
150     return volumeStream;
151 }
152 
GetHistoryVolume(uint32_t sessionId)153 float AudioVolume::GetHistoryVolume(uint32_t sessionId)
154 {
155     Trace trace("AudioVolume::GetHistoryVolume sessionId:" + std::to_string(sessionId));
156     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
157     auto it = historyVolume_.find(sessionId);
158     if (it != historyVolume_.end()) {
159         return it->second;
160     }
161     return 0.0f;
162 }
163 
SetHistoryVolume(uint32_t sessionId,float volume)164 void AudioVolume::SetHistoryVolume(uint32_t sessionId, float volume)
165 {
166     AUDIO_INFO_LOG("history volume, sessionId:%{public}u, volume:%{public}f", sessionId, volume);
167     Trace trace("AudioVolume::SetHistoryVolume sessionId:" + std::to_string(sessionId));
168     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
169     auto it = historyVolume_.find(sessionId);
170     if (it != historyVolume_.end()) {
171         it->second = volume;
172     }
173 }
174 
AddStreamVolume(uint32_t sessionId,int32_t streamType,int32_t streamUsage,int32_t uid,int32_t pid)175 void AudioVolume::AddStreamVolume(uint32_t sessionId, int32_t streamType, int32_t streamUsage,
176     int32_t uid, int32_t pid)
177 {
178     AUDIO_INFO_LOG("stream volume, sessionId:%{public}u", sessionId);
179     std::unique_lock<std::shared_mutex> lock(volumeMutex_);
180     auto it = streamVolume_.find(sessionId);
181     if (it == streamVolume_.end()) {
182         streamVolume_.emplace(sessionId, StreamVolume(sessionId, streamType, streamUsage, uid, pid));
183         historyVolume_.emplace(sessionId, 0.0f);
184         monitorVolume_.emplace(sessionId, std::make_pair(0.0f, 0));
185     } else {
186         AUDIO_ERR_LOG("stream volume already exist, sessionId:%{public}u", sessionId);
187     }
188 }
189 
RemoveStreamVolume(uint32_t sessionId)190 void AudioVolume::RemoveStreamVolume(uint32_t sessionId)
191 {
192     AUDIO_INFO_LOG("stream volume, sessionId:%{public}u", sessionId);
193     std::unique_lock<std::shared_mutex> lock(volumeMutex_);
194     auto it = streamVolume_.find(sessionId);
195     if (it != streamVolume_.end()) {
196         streamVolume_.erase(sessionId);
197     } else {
198         AUDIO_ERR_LOG("stream volume already delete, sessionId:%{public}u", sessionId);
199     }
200     auto itHistory = historyVolume_.find(sessionId);
201     if (itHistory != historyVolume_.end()) {
202         historyVolume_.erase(sessionId);
203     }
204     auto itMonitor = monitorVolume_.find(sessionId);
205     if (itMonitor != monitorVolume_.end()) {
206         monitorVolume_.erase(sessionId);
207     }
208 }
209 
SetStreamVolume(uint32_t sessionId,float volume)210 void AudioVolume::SetStreamVolume(uint32_t sessionId, float volume)
211 {
212     AUDIO_INFO_LOG("stream volume, sessionId:%{public}u, volume:%{public}f", sessionId, volume);
213     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
214     auto it = streamVolume_.find(sessionId);
215     if (it != streamVolume_.end()) {
216         it->second.volume_ = volume;
217     } else {
218         AUDIO_ERR_LOG("stream volume not exist, sessionId:%{public}u", sessionId);
219     }
220 }
221 
SetStreamVolumeDuckFactor(uint32_t sessionId,float duckFactor)222 void AudioVolume::SetStreamVolumeDuckFactor(uint32_t sessionId, float duckFactor)
223 {
224     AUDIO_INFO_LOG("stream volume, sessionId:%{public}u, duckFactor:%{public}f", sessionId, duckFactor);
225     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
226     auto it = streamVolume_.find(sessionId);
227     if (it != streamVolume_.end()) {
228         it->second.duckFactor_ = duckFactor;
229     } else {
230         AUDIO_ERR_LOG("stream volume not exist, sessionId:%{public}u", sessionId);
231     }
232 }
233 
SetStreamVolumeLowPowerFactor(uint32_t sessionId,float lowPowerFactor)234 void AudioVolume::SetStreamVolumeLowPowerFactor(uint32_t sessionId, float lowPowerFactor)
235 {
236     AUDIO_INFO_LOG("stream volume, sessionId:%{public}u, lowPowerFactor:%{public}f", sessionId, lowPowerFactor);
237     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
238     auto it = streamVolume_.find(sessionId);
239     if (it != streamVolume_.end()) {
240         it->second.lowPowerFactor_ = lowPowerFactor;
241     } else {
242         AUDIO_ERR_LOG("stream volume not exist, sessionId:%{public}u", sessionId);
243     }
244 }
245 
SetStreamVolumeMute(uint32_t sessionId,bool isMuted)246 void AudioVolume::SetStreamVolumeMute(uint32_t sessionId, bool isMuted)
247 {
248     AUDIO_INFO_LOG("stream volume, sessionId:%{public}u, isMuted:%{public}d", sessionId, isMuted);
249     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
250     auto it = streamVolume_.find(sessionId);
251     if (it != streamVolume_.end()) {
252         it->second.isMuted_ = isMuted;
253     }
254 }
255 
SetStreamVolumeFade(uint32_t sessionId,float fadeBegin,float fadeEnd)256 void AudioVolume::SetStreamVolumeFade(uint32_t sessionId, float fadeBegin, float fadeEnd)
257 {
258     AUDIO_INFO_LOG("stream volume, sessionId:%{public}u, fadeBegin:%{public}f, fadeEnd:%{public}f",
259         sessionId, fadeBegin, fadeEnd);
260     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
261     auto it = streamVolume_.find(sessionId);
262     if (it != streamVolume_.end()) {
263         it->second.fadeBegin_ = fadeBegin;
264         it->second.fadeEnd_ = fadeEnd;
265     } else {
266         AUDIO_ERR_LOG("stream volume not exist, sessionId:%{public}u", sessionId);
267     }
268 }
269 
GetStreamVolumeFade(uint32_t sessionId)270 std::pair<float, float> AudioVolume::GetStreamVolumeFade(uint32_t sessionId)
271 {
272     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
273     auto it = streamVolume_.find(sessionId);
274     if (it != streamVolume_.end()) {
275         return {it->second.fadeBegin_, it->second.fadeEnd_};
276     } else {
277         AUDIO_ERR_LOG("stream volume not exist, sessionId:%{public}u", sessionId);
278     }
279     return {1.0f, 1.0f};
280 }
281 
SetSystemVolume(SystemVolume & systemVolume)282 void AudioVolume::SetSystemVolume(SystemVolume &systemVolume)
283 {
284     auto volumeType = systemVolume.GetVolumeType();
285     auto deviceClass = systemVolume.GetDeviceClass();
286     std::string key = std::to_string(volumeType) + deviceClass;
287     bool haveSystemVolume = true;
288     {
289         std::shared_lock<std::shared_mutex> lock(systemMutex_);
290         auto it = systemVolume_.find(key);
291         if (it != systemVolume_.end()) {
292             it->second.volume_ = systemVolume.volume_;
293             it->second.volumeLevel_ = systemVolume.volumeLevel_;
294             it->second.isMuted_ = systemVolume.isMuted_;
295         } else {
296             haveSystemVolume = false;
297         }
298     }
299     if (!haveSystemVolume) {
300         std::unique_lock<std::shared_mutex> lock(systemMutex_);
301         systemVolume_.emplace(key, systemVolume);
302     }
303     AUDIO_INFO_LOG("system volume, volumeType:%{public}d, deviceClass:%{public}s,"
304         " volume:%{public}f, volumeLevel:%{public}d, isMuted:%{public}d, systemVolumeSize:%{public}zu",
305         volumeType, deviceClass.c_str(), systemVolume.volume_, systemVolume.volumeLevel_, systemVolume.isMuted_,
306         systemVolume_.size());
307 }
308 
SetSystemVolume(int32_t volumeType,const std::string & deviceClass,float volume,int32_t volumeLevel)309 void AudioVolume::SetSystemVolume(int32_t volumeType, const std::string &deviceClass, float volume, int32_t volumeLevel)
310 {
311     std::string key = std::to_string(volumeType) + deviceClass;
312     bool haveSystemVolume = true;
313     {
314         std::shared_lock<std::shared_mutex> lock(systemMutex_);
315         auto it = systemVolume_.find(key);
316         if (it != systemVolume_.end()) {
317             it->second.volume_ = volume;
318             it->second.volumeLevel_ = volumeLevel;
319         } else {
320             haveSystemVolume = false;
321         }
322     }
323     if (!haveSystemVolume) {
324         std::unique_lock<std::shared_mutex> lock(systemMutex_);
325         SystemVolume systemVolume(volumeType, deviceClass, volume, volumeLevel, false);
326         systemVolume_.emplace(key, systemVolume);
327     }
328     AUDIO_INFO_LOG("system volume, volumeType:%{public}d, deviceClass:%{public}s,"
329         " volume:%{public}f, volumeLevel:%{public}d, systemVolumeSize:%{public}zu",
330         volumeType, deviceClass.c_str(), volume, volumeLevel, systemVolume_.size());
331 }
332 
SetSystemVolumeMute(int32_t volumeType,const std::string & deviceClass,bool isMuted)333 void AudioVolume::SetSystemVolumeMute(int32_t volumeType, const std::string &deviceClass, bool isMuted)
334 {
335     AUDIO_INFO_LOG("system volume, volumeType:%{public}d, deviceClass:%{public}s, isMuted:%{public}d",
336         volumeType, deviceClass.c_str(), isMuted);
337     std::string key = std::to_string(volumeType) + deviceClass;
338     bool haveSystemVolume = true;
339     {
340         std::shared_lock<std::shared_mutex> lock(systemMutex_);
341         auto it = systemVolume_.find(key);
342         if (it != systemVolume_.end()) {
343             it->second.isMuted_ = isMuted;
344         } else {
345             haveSystemVolume = false;
346         }
347     }
348     if (!haveSystemVolume) {
349         std::unique_lock<std::shared_mutex> lock(systemMutex_);
350         SystemVolume systemVolume(volumeType, deviceClass, 0.0f, 0, isMuted);
351         systemVolume_.emplace(key, systemVolume);
352     }
353 }
354 
ConvertStreamTypeStrToInt(const std::string & streamType)355 int32_t AudioVolume::ConvertStreamTypeStrToInt(const std::string &streamType)
356 {
357     AudioStreamType stream = STREAM_MUSIC;
358     if (STREAM_TYPE_STRING_ENUM_MAP.find(streamType) != STREAM_TYPE_STRING_ENUM_MAP.end()) {
359         stream = STREAM_TYPE_STRING_ENUM_MAP.at(streamType);
360     } else {
361         AUDIO_WARNING_LOG("Invalid stream type [%{public}s]. Use default type", streamType.c_str());
362     }
363     return stream;
364 }
365 
IsSameVolume(float x,float y)366 bool AudioVolume::IsSameVolume(float x, float y)
367 {
368     return (std::abs((x) - (y)) <= std::abs(FLOAT_EPS));
369 }
370 
Dump(std::string & dumpString)371 void AudioVolume::Dump(std::string &dumpString)
372 {
373     AUDIO_INFO_LOG("AudioVolume dump begin");
374     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
375     // dump system volume
376     std::vector<SystemVolume> systemVolumeList;
377     for (auto &systemVolume : systemVolume_) {
378         systemVolumeList.push_back(systemVolume.second);
379     }
380     std::sort(systemVolumeList.begin(), systemVolumeList.end(), [](SystemVolume &a, SystemVolume &b) {
381         return a.GetVolumeType() < b.GetVolumeType();
382     });
383     AppendFormat(dumpString, "\n  - audio system volume size: %zu\n", systemVolumeList.size());
384     for (auto &systemVolume : systemVolumeList) {
385         AppendFormat(dumpString, "  streamtype: %d ", systemVolume.GetVolumeType());
386         AppendFormat(dumpString, "  isMute: %s ", (systemVolume.isMuted_ ? "true" : "false"));
387         AppendFormat(dumpString, "  volFloat: %f ", systemVolume.volume_);
388         AppendFormat(dumpString, "  volInt: %d ", systemVolume.volumeLevel_);
389         AppendFormat(dumpString, "  device class: %s \n", systemVolume.GetDeviceClass().c_str());
390     }
391 
392     // dump stream volume
393     std::vector<StreamVolume> streamVolumeList;
394     for (auto &streamVolume : streamVolume_) {
395         streamVolumeList.push_back(streamVolume.second);
396     }
397     std::sort(streamVolumeList.begin(), streamVolumeList.end(), [](StreamVolume &a, StreamVolume &b) {
398         return a.GetSessionId() < b.GetSessionId();
399     });
400     AppendFormat(dumpString, "\n  - audio stream volume size: %zu, his volume size: %zu, mon volume size: %zu\n",
401         streamVolumeList.size(), historyVolume_.size(), monitorVolume_.size());
402     for (auto &streamVolume : streamVolumeList) {
403         auto monVol = monitorVolume_.find(streamVolume.GetSessionId());
404         AppendFormat(dumpString, "  sessionId: %u ", streamVolume.GetSessionId());
405         AppendFormat(dumpString, "  streamType: %d ", streamVolume.GetStreamType());
406         AppendFormat(dumpString, "  streamUsage: %d ", streamVolume.GetStreamUsage());
407         AppendFormat(dumpString, "  appUid: %d ", streamVolume.GetAppUid());
408         AppendFormat(dumpString, "  appPid: %d ", streamVolume.GetAppPid());
409         AppendFormat(dumpString, "  volume: %f ", monVol != monitorVolume_.end() ? monVol->second.first : 0.0f);
410         AppendFormat(dumpString, "  volumeLevel: %d ",  monVol != monitorVolume_.end() ? monVol->second.second : 0);
411         AppendFormat(dumpString, "  volFactor: %f ", streamVolume.volume_);
412         AppendFormat(dumpString, "  duckFactor: %f ", streamVolume.duckFactor_);
413         AppendFormat(dumpString, "  powerFactor: %f ", streamVolume.lowPowerFactor_);
414         AppendFormat(dumpString, "  fadeBegin: %f ", streamVolume.fadeBegin_);
415         AppendFormat(dumpString, "  fadeEnd: %f \n", streamVolume.fadeEnd_);
416     }
417 }
418 
Monitor(uint32_t sessionId,bool isOutput)419 void AudioVolume::Monitor(uint32_t sessionId, bool isOutput)
420 {
421     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
422     auto streamVolume = streamVolume_.find(sessionId);
423     if (streamVolume != streamVolume_.end()) {
424         auto monVol = monitorVolume_.find(sessionId);
425         std::shared_ptr<Media::MediaMonitor::EventBean> bean = std::make_shared<Media::MediaMonitor::EventBean>(
426             Media::MediaMonitor::AUDIO, Media::MediaMonitor::VOLUME_CHANGE,
427             Media::MediaMonitor::BEHAVIOR_EVENT);
428         bean->Add("ISOUTPUT", isOutput ? 1 : 0);
429         bean->Add("STREAMID", static_cast<int32_t>(sessionId));
430         bean->Add("APP_UID", streamVolume->second.GetAppUid());
431         bean->Add("APP_PID", streamVolume->second.GetAppPid());
432         bean->Add("STREAMTYPE", streamVolume->second.GetStreamType());
433         bean->Add("STREAM_TYPE", streamVolume->second.GetStreamUsage());
434         bean->Add("VOLUME", monVol != monitorVolume_.end() ? monVol->second.first : 0.0f);
435         bean->Add("SYSVOLUME", monVol != monitorVolume_.end() ? monVol->second.second : 0);
436         bean->Add("VOLUMEFACTOR", streamVolume->second.volume_);
437         bean->Add("POWERVOLUMEFACTOR", streamVolume->second.lowPowerFactor_);
438         Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
439     } else {
440         AUDIO_ERR_LOG("stream volume not exist, sessionId:%{public}u", sessionId);
441     }
442 }
443 
SetFadeoutState(uint32_t streamIndex,uint32_t fadeoutState)444 void AudioVolume::SetFadeoutState(uint32_t streamIndex, uint32_t fadeoutState)
445 {
446     std::unique_lock<std::shared_mutex> lock(fadoutMutex_);
447     fadeoutState_.insert_or_assign(streamIndex, fadeoutState);
448 }
449 
GetFadeoutState(uint32_t streamIndex)450 uint32_t AudioVolume::GetFadeoutState(uint32_t streamIndex)
451 {
452     std::shared_lock<std::shared_mutex> lock(fadoutMutex_);
453     auto it = fadeoutState_.find(streamIndex);
454     if (it != fadeoutState_.end()) { return it->second; }
455     AUDIO_WARNING_LOG("No such streamIndex in map!");
456     return INVALID_STATE;
457 }
458 
RemoveFadeoutState(uint32_t streamIndex)459 void AudioVolume::RemoveFadeoutState(uint32_t streamIndex)
460 {
461     std::unique_lock<std::shared_mutex> lock(fadoutMutex_);
462     fadeoutState_.erase(streamIndex);
463 }
464 } // namespace AudioStandard
465 } // namespace OHOS
466 
467 #ifdef __cplusplus
468 extern "C" {
469 #endif
470 using namespace OHOS::AudioStandard;
471 
GetCurVolume(uint32_t sessionId,const char * streamType,const char * deviceClass)472 float GetCurVolume(uint32_t sessionId, const char *streamType, const char *deviceClass)
473 {
474     CHECK_AND_RETURN_RET_LOG(streamType != nullptr, 1.0f, "streamType is nullptr");
475     CHECK_AND_RETURN_RET_LOG(deviceClass != nullptr, 1.0f, "deviceClass is nullptr");
476     std::string tmpStreamType = streamType;
477     // Set voice call assistant stream type to full volume
478     if (tmpStreamType == "voice_call_assistant") {
479         return 1.0f;
480     }
481     int32_t stream = AudioVolume::GetInstance()->ConvertStreamTypeStrToInt(streamType);
482     AudioStreamType volumeType = VolumeUtils::GetVolumeTypeFromStreamType(static_cast<AudioStreamType>(stream));
483     return AudioVolume::GetInstance()->GetVolume(sessionId, volumeType, deviceClass);
484 }
485 
GetStreamVolume(uint32_t sessionId)486 float GetStreamVolume(uint32_t sessionId)
487 {
488     return AudioVolume::GetInstance()->GetStreamVolume(sessionId);
489 }
490 
GetPreVolume(uint32_t sessionId)491 float GetPreVolume(uint32_t sessionId)
492 {
493     return AudioVolume::GetInstance()->GetHistoryVolume(sessionId);
494 }
495 
SetPreVolume(uint32_t sessionId,float volume)496 void SetPreVolume(uint32_t sessionId, float volume)
497 {
498     AudioVolume::GetInstance()->SetHistoryVolume(sessionId, volume);
499 }
500 
GetStreamVolumeFade(uint32_t sessionId,float * fadeBegin,float * fadeEnd)501 void GetStreamVolumeFade(uint32_t sessionId, float *fadeBegin, float *fadeEnd)
502 {
503     auto fade = AudioVolume::GetInstance()->GetStreamVolumeFade(sessionId);
504     *fadeBegin = fade.first;
505     *fadeEnd = fade.second;
506 }
507 
SetStreamVolumeFade(uint32_t sessionId,float fadeBegin,float fadeEnd)508 void SetStreamVolumeFade(uint32_t sessionId, float fadeBegin, float fadeEnd)
509 {
510     AudioVolume::GetInstance()->SetStreamVolumeFade(sessionId, fadeBegin, fadeEnd);
511 }
512 
IsSameVolume(float x,float y)513 bool IsSameVolume(float x, float y)
514 {
515     return AudioVolume::GetInstance()->IsSameVolume(x, y);
516 }
517 
MonitorVolume(uint32_t sessionId,bool isOutput)518 void MonitorVolume(uint32_t sessionId, bool isOutput)
519 {
520     AudioVolume::GetInstance()->Monitor(sessionId, isOutput);
521 }
522 
SetFadeoutState(uint32_t streamIndex,uint32_t fadeoutState)523 void SetFadeoutState(uint32_t streamIndex, uint32_t fadeoutState)
524 {
525     AudioVolume::GetInstance()->SetFadeoutState(streamIndex, fadeoutState);
526 }
527 
GetFadeoutState(uint32_t streamIndex)528 uint32_t GetFadeoutState(uint32_t streamIndex)
529 {
530     return AudioVolume::GetInstance()->GetFadeoutState(streamIndex);
531 }
532 
GetFadeStrategy(uint64_t expectedPlaybackDurationMs)533 FadeStrategy GetFadeStrategy(uint64_t expectedPlaybackDurationMs)
534 {
535     // 0 is default; duration > 40ms do default fade
536     if (expectedPlaybackDurationMs == 0 || expectedPlaybackDurationMs > DURATION_TIME_DEFAULT) {
537         return FADE_STRATEGY_DEFAULT;
538     }
539 
540     // duration <= 10 ms no fade
541     if (expectedPlaybackDurationMs <= DURATION_TIME_SHORT && expectedPlaybackDurationMs > 0) {
542         return FADE_STRATEGY_NONE;
543     }
544 
545     // duration > 10ms && duration <= 40ms do 5ms fade
546     if (expectedPlaybackDurationMs <= DURATION_TIME_DEFAULT && expectedPlaybackDurationMs > DURATION_TIME_SHORT) {
547         return FADE_STRATEGY_SHORTER;
548     }
549 
550     return FADE_STRATEGY_DEFAULT;
551 }
552 #ifdef __cplusplus
553 }
554 #endif