• 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 <numeric>
21 #include "audio_volume.h"
22 #include "audio_volume_c.h"
23 #include "audio_common_log.h"
24 #include "audio_utils.h"
25 #include "audio_stream_info.h"
26 #include "media_monitor_manager.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 static const  float DEFAULT_APP_VOLUME = 1.0f;
59 
GetInstance()60 AudioVolume *AudioVolume::GetInstance()
61 {
62     static AudioVolume instance;
63     return &instance;
64 }
65 
AudioVolume()66 AudioVolume::AudioVolume()
67 {
68     AUDIO_INFO_LOG("AudioVolume construct");
69 }
70 
~AudioVolume()71 AudioVolume::~AudioVolume()
72 {
73     appVolume_.clear();
74     streamVolume_.clear();
75     systemVolume_.clear();
76     historyVolume_.clear();
77     monitorVolume_.clear();
78 }
79 
GetVolume(uint32_t sessionId,int32_t volumeType,const std::string & deviceClass)80 float AudioVolume::GetVolume(uint32_t sessionId, int32_t volumeType, const std::string &deviceClass)
81 {
82     Trace trace("AudioVolume::GetVolume");
83     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
84     int32_t volumeLevel = 0;
85     int32_t appUid = -1;
86     AudioVolumeMode volumeMode = AUDIOSTREAM_VOLUMEMODE_SYSTEM_GLOBAL;
87     float volumeStream = GetStreamVolumeInternal(sessionId, volumeType, appUid, volumeMode);
88     float volumeSystem = GetSystemVolumeInternal(volumeType, deviceClass, volumeLevel);
89     float volumeApp = GetAppVolume(appUid, volumeMode);
90     float volumeFloat = volumeStream * volumeSystem * volumeApp;
91     if (IsChangeVolume(sessionId, volumeFloat, volumeLevel)) {
92         AUDIO_INFO_LOG("volume, sessionId:%{public}u, volume:%{public}f, volumeType:%{public}d, devClass:%{public}s,"
93             " system volume:%{public}f, stream volume:%{public}f app volume:%{public}f",
94             sessionId, volumeFloat, volumeType, deviceClass.c_str(),
95             volumeSystem, volumeStream, volumeApp);
96     }
97     return volumeFloat;
98 }
99 
IsChangeVolume(uint32_t sessionId,float volumeFloat,int32_t volumeLevel)100 bool AudioVolume::IsChangeVolume(uint32_t sessionId, float volumeFloat, int32_t volumeLevel)
101 {
102     bool isChange = false;
103     if (monitorVolume_.find(sessionId) != monitorVolume_.end()) {
104         if (monitorVolume_[sessionId].first != volumeFloat) {
105             isChange = true;
106         }
107         monitorVolume_[sessionId] = {volumeFloat, volumeLevel};
108     }
109     return isChange;
110 }
111 
GetStreamVolumeInternal(uint32_t sessionId,int32_t & volumeType,int32_t & appUid,AudioVolumeMode & volumeMode)112 float AudioVolume::GetStreamVolumeInternal(uint32_t sessionId, int32_t& volumeType,
113     int32_t& appUid, AudioVolumeMode& volumeMode)
114 {
115     AudioStreamType volumeMapType = VolumeUtils::GetVolumeTypeFromStreamType(static_cast<AudioStreamType>(volumeType));
116     float volumeStream = 1.0f;
117     auto it = streamVolume_.find(sessionId);
118     if (it != streamVolume_.end()) {
119         volumeStream =
120             it->second.isMuted_ ? 0.0f : it->second.volume_ * it->second.duckFactor_ * it->second.lowPowerFactor_;
121         appUid = it->second.GetAppUid();
122         volumeMode = static_cast<AudioVolumeMode>(it->second.GetvolumeMode());
123         AUDIO_DEBUG_LOG("stream volume, sessionId:%{public}u, volume:%{public}f, duck:%{public}f, lowPower:%{public}f,"
124             " isMuted:%{public}d, streamVolumeSize:%{public}zu",
125             sessionId, it->second.volume_, it->second.duckFactor_, it->second.lowPowerFactor_, it->second.isMuted_,
126             streamVolume_.size());
127         if (volumeMapType == STREAM_VOICE_ASSISTANT && !it->second.isSystemApp()) {
128             volumeType = STREAM_MUSIC;
129         }
130     } else {
131         AUDIO_ERR_LOG("stream volume not exist, sessionId:%{public}u, streamVolumeSize:%{public}zu",
132             sessionId, streamVolume_.size());
133     }
134     return volumeStream;
135 }
136 
GetSystemVolumeInternal(int32_t volumeType,const std::string & deviceClass,int32_t & volumeLevel)137 float AudioVolume::GetSystemVolumeInternal(int32_t volumeType, const std::string &deviceClass, int32_t& volumeLevel)
138 {
139     std::shared_lock<std::shared_mutex> lock(systemMutex_);
140     AudioStreamType volumeMapType = VolumeUtils::GetVolumeTypeFromStreamType(static_cast<AudioStreamType>(volumeType));
141     float volumeSystem = 1.0f;
142     std::string key = std::to_string(volumeMapType) + deviceClass;
143     auto itSV = systemVolume_.find(key);
144     if (itSV != systemVolume_.end()) {
145         volumeLevel = itSV->second.volumeLevel_;
146         volumeSystem = itSV->second.isMuted_ ? 0.0f : itSV->second.volume_;
147         AUDIO_DEBUG_LOG("system volume, volumeType:%{public}d, deviceClass:%{public}s,"
148             " volume:%{public}f, isMuted:%{public}d, systemVolumeSize:%{public}zu",
149             volumeMapType, deviceClass.c_str(), itSV->second.volume_, itSV->second.isMuted_, systemVolume_.size());
150     } else {
151         AUDIO_ERR_LOG("system volume not exist, volumeType:%{public}d, deviceClass:%{public}s,"
152             " systemVolumeSize:%{public}zu", volumeMapType, deviceClass.c_str(), systemVolume_.size());
153     }
154     if (AudioVolume::GetInstance()->IsVgsVolumeSupported() && volumeSystem > 0.0f &&
155         (volumeType == STREAM_VOICE_CALL || volumeType == STREAM_VOICE_COMMUNICATION)) {
156         volumeSystem = 1.0f;
157     }
158     return volumeSystem;
159 }
160 
GetStreamVolume(uint32_t sessionId)161 float AudioVolume::GetStreamVolume(uint32_t sessionId)
162 {
163     Trace trace("AudioVolume::GetStreamVolume sessionId:" + std::to_string(sessionId));
164     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
165     float volumeStream = 1.0f;
166     auto it = streamVolume_.find(sessionId);
167     if (it != streamVolume_.end()) {
168         volumeStream =
169             it->second.isMuted_ ? 0.0f : it->second.volume_ * it->second.duckFactor_ * it->second.lowPowerFactor_;
170         AUDIO_DEBUG_LOG("stream volume, sessionId:%{public}u, volume:%{public}f, duck:%{public}f, lowPower:%{public}f,"
171             " isMuted:%{public}d, streamVolumeSize:%{public}zu",
172             sessionId, it->second.volume_, it->second.duckFactor_, it->second.lowPowerFactor_, it->second.isMuted_,
173             streamVolume_.size());
174     } else {
175         AUDIO_ERR_LOG("stream volume not exist, sessionId:%{public}u, streamVolumeSize:%{public}zu",
176             sessionId, streamVolume_.size());
177     }
178     if (monitorVolume_.find(sessionId) != monitorVolume_.end()) {
179         if (monitorVolume_[sessionId].first != volumeStream) {
180             AUDIO_INFO_LOG("volume, sessionId:%{public}u, stream volume:%{public}f", sessionId, volumeStream);
181         }
182         monitorVolume_[sessionId] = {volumeStream, 15}; // 15 level only stream volume
183     }
184     Trace traceVolume("Volume, sessionId:" + std::to_string(sessionId) +
185         ", stream volume:" + std::to_string(volumeStream));
186     return volumeStream;
187 }
188 
GetHistoryVolume(uint32_t sessionId)189 float AudioVolume::GetHistoryVolume(uint32_t sessionId)
190 {
191     Trace trace("AudioVolume::GetHistoryVolume sessionId:" + std::to_string(sessionId));
192     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
193     auto it = historyVolume_.find(sessionId);
194     if (it != historyVolume_.end()) {
195         return it->second;
196     }
197     return 0.0f;
198 }
199 
SetHistoryVolume(uint32_t sessionId,float volume)200 void AudioVolume::SetHistoryVolume(uint32_t sessionId, float volume)
201 {
202     AUDIO_INFO_LOG("history volume, sessionId:%{public}u, volume:%{public}f", sessionId, volume);
203     Trace trace("AudioVolume::SetHistoryVolume sessionId:" + std::to_string(sessionId));
204     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
205     auto it = historyVolume_.find(sessionId);
206     if (it != historyVolume_.end()) {
207         it->second = volume;
208     }
209 }
210 
AddStreamVolume(uint32_t sessionId,int32_t streamType,int32_t streamUsage,int32_t uid,int32_t pid,bool isSystemApp,int32_t mode)211 void AudioVolume::AddStreamVolume(uint32_t sessionId, int32_t streamType, int32_t streamUsage,
212     int32_t uid, int32_t pid, bool isSystemApp, int32_t mode)
213 {
214     AUDIO_INFO_LOG("stream volume, sessionId:%{public}u", sessionId);
215     std::unique_lock<std::shared_mutex> lock(volumeMutex_);
216     auto it = streamVolume_.find(sessionId);
217     if (it == streamVolume_.end()) {
218         streamVolume_.emplace(sessionId,
219             StreamVolume(sessionId, streamType, streamUsage, uid, pid, isSystemApp, mode));
220         historyVolume_.emplace(sessionId, 0.0f);
221         monitorVolume_.emplace(sessionId, std::make_pair(0.0f, 0));
222     } else {
223         AUDIO_ERR_LOG("stream volume already exist, sessionId:%{public}u", sessionId);
224     }
225 }
226 
RemoveStreamVolume(uint32_t sessionId)227 void AudioVolume::RemoveStreamVolume(uint32_t sessionId)
228 {
229     AUDIO_INFO_LOG("stream volume, sessionId:%{public}u", sessionId);
230     std::unique_lock<std::shared_mutex> lock(volumeMutex_);
231     auto it = streamVolume_.find(sessionId);
232     if (it != streamVolume_.end()) {
233         streamVolume_.erase(sessionId);
234     } else {
235         AUDIO_ERR_LOG("stream volume already delete, sessionId:%{public}u", sessionId);
236     }
237     auto itHistory = historyVolume_.find(sessionId);
238     if (itHistory != historyVolume_.end()) {
239         historyVolume_.erase(sessionId);
240     }
241     auto itMonitor = monitorVolume_.find(sessionId);
242     if (itMonitor != monitorVolume_.end()) {
243         monitorVolume_.erase(sessionId);
244     }
245 }
246 
SetStreamVolume(uint32_t sessionId,float volume)247 void AudioVolume::SetStreamVolume(uint32_t sessionId, float volume)
248 {
249     AUDIO_INFO_LOG("stream volume, sessionId:%{public}u, volume:%{public}f", sessionId, volume);
250     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
251     auto it = streamVolume_.find(sessionId);
252     if (it != streamVolume_.end()) {
253         it->second.volume_ = volume;
254     } else {
255         AUDIO_ERR_LOG("stream volume not exist, sessionId:%{public}u", sessionId);
256     }
257 }
258 
SetStreamVolumeDuckFactor(uint32_t sessionId,float duckFactor)259 void AudioVolume::SetStreamVolumeDuckFactor(uint32_t sessionId, float duckFactor)
260 {
261     AUDIO_INFO_LOG("stream volume, sessionId:%{public}u, duckFactor:%{public}f", sessionId, duckFactor);
262     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
263     auto it = streamVolume_.find(sessionId);
264     if (it != streamVolume_.end()) {
265         it->second.duckFactor_ = duckFactor;
266     } else {
267         AUDIO_ERR_LOG("stream volume not exist, sessionId:%{public}u", sessionId);
268     }
269 }
270 
SetStreamVolumeLowPowerFactor(uint32_t sessionId,float lowPowerFactor)271 void AudioVolume::SetStreamVolumeLowPowerFactor(uint32_t sessionId, float lowPowerFactor)
272 {
273     AUDIO_INFO_LOG("stream volume, sessionId:%{public}u, lowPowerFactor:%{public}f", sessionId, lowPowerFactor);
274     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
275     auto it = streamVolume_.find(sessionId);
276     if (it != streamVolume_.end()) {
277         it->second.lowPowerFactor_ = lowPowerFactor;
278     } else {
279         AUDIO_ERR_LOG("stream volume not exist, sessionId:%{public}u", sessionId);
280     }
281 }
282 
SetStreamVolumeMute(uint32_t sessionId,bool isMuted)283 void AudioVolume::SetStreamVolumeMute(uint32_t sessionId, bool isMuted)
284 {
285     AUDIO_INFO_LOG("stream volume, sessionId:%{public}u, isMuted:%{public}d", sessionId, isMuted);
286     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
287     auto it = streamVolume_.find(sessionId);
288     if (it != streamVolume_.end()) {
289         it->second.isMuted_ = isMuted;
290     }
291 }
292 
SetStreamVolumeFade(uint32_t sessionId,float fadeBegin,float fadeEnd)293 void AudioVolume::SetStreamVolumeFade(uint32_t sessionId, float fadeBegin, float fadeEnd)
294 {
295     AUDIO_INFO_LOG("stream volume, sessionId:%{public}u, fadeBegin:%{public}f, fadeEnd:%{public}f",
296         sessionId, fadeBegin, fadeEnd);
297     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
298     auto it = streamVolume_.find(sessionId);
299     if (it != streamVolume_.end()) {
300         it->second.fadeBegin_ = fadeBegin;
301         it->second.fadeEnd_ = fadeEnd;
302     } else {
303         AUDIO_ERR_LOG("stream volume not exist, sessionId:%{public}u", sessionId);
304     }
305 }
306 
GetStreamVolumeFade(uint32_t sessionId)307 std::pair<float, float> AudioVolume::GetStreamVolumeFade(uint32_t sessionId)
308 {
309     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
310     auto it = streamVolume_.find(sessionId);
311     if (it != streamVolume_.end()) {
312         return {it->second.fadeBegin_, it->second.fadeEnd_};
313     } else {
314         AUDIO_ERR_LOG("stream volume not exist, sessionId:%{public}u", sessionId);
315     }
316     return {1.0f, 1.0f};
317 }
318 
GetAppVolume(int32_t appUid,AudioVolumeMode mode)319 float AudioVolume::GetAppVolume(int32_t appUid, AudioVolumeMode mode)
320 {
321     AUDIO_DEBUG_LOG("Get app volume, appUid = %{public}d, mode = %{public}d", appUid, mode);
322     std::shared_lock<std::shared_mutex> lock(appMutex_);
323     float appVolume = 1.0f;
324     auto iter = appVolume_.find(appUid);
325     if (iter != appVolume_.end()) {
326         AUDIO_DEBUG_LOG("find appVolume, mute = %{public}d, volume = %{public}f",
327             iter->second.isMuted_, iter->second.volume_);
328         appVolume = iter->second.isMuted_ ? 0 : iter->second.volume_;
329     }
330     AUDIO_DEBUG_LOG("appVolume = %{public}f", appVolume);
331     appVolume = (mode == AUDIOSTREAM_VOLUMEMODE_SYSTEM_GLOBAL) ? 1.0 : appVolume;
332     return appVolume;
333 }
334 
SetAppVolumeMute(int32_t appUid,bool isMuted)335 void AudioVolume::SetAppVolumeMute(int32_t appUid, bool isMuted)
336 {
337     bool haveAppVolume = true;
338     {
339         std::shared_lock<std::shared_mutex> lock(appMutex_);
340         auto it = appVolume_.find(appUid);
341         if (it != appVolume_.end()) {
342             it->second.isMuted_ = isMuted;
343         } else {
344             haveAppVolume = false;
345         }
346     }
347     if (!haveAppVolume) {
348         std::unique_lock<std::shared_mutex> lock(appMutex_);
349         AppVolume appVolume(appUid, DEFAULT_APP_VOLUME, defaultAppVolume_, isMuted);
350         appVolume_.emplace(appUid, appVolume);
351     }
352     AUDIO_INFO_LOG("set volume mute, appUId:%{public}d, isMuted:%{public}d, systemVolumeSize:%{public}zu",
353         appUid, isMuted, appVolume_.size());
354 }
355 
SetAppVolume(AppVolume & appVolume)356 void AudioVolume::SetAppVolume(AppVolume &appVolume)
357 {
358     int32_t appUid = appVolume.GetAppUid();
359     bool haveAppVolume = true;
360     {
361         std::shared_lock<std::shared_mutex> lock(appMutex_);
362         auto it = appVolume_.find(appUid);
363         if (it != appVolume_.end()) {
364             it->second.volume_ = appVolume.volume_;
365             it->second.volumeLevel_ = appVolume.volumeLevel_;
366             it->second.isMuted_ = appVolume.isMuted_;
367         } else {
368             haveAppVolume = false;
369         }
370     }
371     if (!haveAppVolume) {
372         std::unique_lock<std::shared_mutex> lock(appMutex_);
373         appVolume_.emplace(appUid, appVolume);
374     }
375     AUDIO_INFO_LOG("system volume, appUId:%{public}d, "
376         " volume:%{public}f, volumeLevel:%{public}d, isMuted:%{public}d, systemVolumeSize:%{public}zu",
377         appUid, appVolume.volume_, appVolume.volumeLevel_, appVolume.isMuted_,
378         appVolume_.size());
379 }
380 
SetDefaultAppVolume(int32_t level)381 void AudioVolume::SetDefaultAppVolume(int32_t level)
382 {
383     defaultAppVolume_ = level;
384 }
385 
SetSystemVolume(SystemVolume & systemVolume)386 void AudioVolume::SetSystemVolume(SystemVolume &systemVolume)
387 {
388     auto volumeType = systemVolume.GetVolumeType();
389     auto deviceClass = systemVolume.GetDeviceClass();
390     std::string key = std::to_string(volumeType) + deviceClass;
391     bool haveSystemVolume = true;
392     {
393         std::shared_lock<std::shared_mutex> lock(systemMutex_);
394         auto it = systemVolume_.find(key);
395         if (it != systemVolume_.end()) {
396             it->second.volume_ = systemVolume.volume_;
397             it->second.volumeLevel_ = systemVolume.volumeLevel_;
398             it->second.isMuted_ = systemVolume.isMuted_;
399         } else {
400             haveSystemVolume = false;
401         }
402     }
403     if (!haveSystemVolume) {
404         std::unique_lock<std::shared_mutex> lock(systemMutex_);
405         systemVolume_.emplace(key, systemVolume);
406     }
407     AUDIO_INFO_LOG("system volume, volumeType:%{public}d, deviceClass:%{public}s,"
408         " volume:%{public}f, volumeLevel:%{public}d, isMuted:%{public}d, systemVolumeSize:%{public}zu",
409         volumeType, deviceClass.c_str(), systemVolume.volume_, systemVolume.volumeLevel_, systemVolume.isMuted_,
410         systemVolume_.size());
411 }
412 
SetSystemVolume(int32_t volumeType,const std::string & deviceClass,float volume,int32_t volumeLevel)413 void AudioVolume::SetSystemVolume(int32_t volumeType, const std::string &deviceClass,
414     float volume, int32_t volumeLevel)
415 {
416     std::string key = std::to_string(volumeType) + deviceClass;
417     bool haveSystemVolume = true;
418     {
419         std::shared_lock<std::shared_mutex> lock(systemMutex_);
420         auto it = systemVolume_.find(key);
421         if (it != systemVolume_.end()) {
422             it->second.volume_ = volume;
423             it->second.volumeLevel_ = volumeLevel;
424         } else {
425             haveSystemVolume = false;
426         }
427     }
428     if (!haveSystemVolume) {
429         std::unique_lock<std::shared_mutex> lock(systemMutex_);
430         SystemVolume systemVolume(volumeType, deviceClass, volume, volumeLevel, false);
431         systemVolume_.emplace(key, systemVolume);
432     }
433     AUDIO_INFO_LOG("system volume, volumeType:%{public}d, deviceClass:%{public}s,"
434         " volume:%{public}f, volumeLevel:%{public}d, systemVolumeSize:%{public}zu",
435         volumeType, deviceClass.c_str(), volume, volumeLevel, systemVolume_.size());
436 }
437 
SetSystemVolumeMute(int32_t volumeType,const std::string & deviceClass,bool isMuted)438 void AudioVolume::SetSystemVolumeMute(int32_t volumeType, const std::string &deviceClass, bool isMuted)
439 {
440     AUDIO_INFO_LOG("system volume, volumeType:%{public}d, deviceClass:%{public}s, isMuted:%{public}d",
441         volumeType, deviceClass.c_str(), isMuted);
442     std::string key = std::to_string(volumeType) + deviceClass;
443     bool haveSystemVolume = true;
444     {
445         std::shared_lock<std::shared_mutex> lock(systemMutex_);
446         auto it = systemVolume_.find(key);
447         if (it != systemVolume_.end()) {
448             it->second.isMuted_ = isMuted;
449         } else {
450             haveSystemVolume = false;
451         }
452     }
453     if (!haveSystemVolume) {
454         std::unique_lock<std::shared_mutex> lock(systemMutex_);
455         SystemVolume systemVolume(volumeType, deviceClass, 0.0f, 0, isMuted);
456         systemVolume_.emplace(key, systemVolume);
457     }
458 }
459 
ConvertStreamTypeStrToInt(const std::string & streamType)460 int32_t AudioVolume::ConvertStreamTypeStrToInt(const std::string &streamType)
461 {
462     AudioStreamType stream = STREAM_MUSIC;
463     if (STREAM_TYPE_STRING_ENUM_MAP.find(streamType) != STREAM_TYPE_STRING_ENUM_MAP.end()) {
464         stream = STREAM_TYPE_STRING_ENUM_MAP.at(streamType);
465     } else {
466         AUDIO_WARNING_LOG("Invalid stream type [%{public}s]. Use default type", streamType.c_str());
467     }
468     return stream;
469 }
470 
IsSameVolume(float x,float y)471 bool AudioVolume::IsSameVolume(float x, float y)
472 {
473     return (std::abs((x) - (y)) <= std::abs(FLOAT_EPS));
474 }
475 
Dump(std::string & dumpString)476 void AudioVolume::Dump(std::string &dumpString)
477 {
478     AUDIO_INFO_LOG("AudioVolume dump begin");
479     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
480     // dump system volume
481     std::vector<SystemVolume> systemVolumeList;
482     for (auto &systemVolume : systemVolume_) {
483         systemVolumeList.push_back(systemVolume.second);
484     }
485     std::sort(systemVolumeList.begin(), systemVolumeList.end(), [](SystemVolume &a, SystemVolume &b) {
486         return a.GetVolumeType() < b.GetVolumeType();
487     });
488     AppendFormat(dumpString, "\n  - audio system volume size: %zu\n", systemVolumeList.size());
489     for (auto &systemVolume : systemVolumeList) {
490         AppendFormat(dumpString, "  streamtype: %d ", systemVolume.GetVolumeType());
491         AppendFormat(dumpString, "  isMute: %s ", (systemVolume.isMuted_ ? "true" : "false"));
492         AppendFormat(dumpString, "  volFloat: %f ", systemVolume.volume_);
493         AppendFormat(dumpString, "  volInt: %d ", systemVolume.volumeLevel_);
494         AppendFormat(dumpString, "  device class: %s \n", systemVolume.GetDeviceClass().c_str());
495     }
496 
497     // dump stream volume
498     std::vector<StreamVolume> streamVolumeList;
499     for (auto &streamVolume : streamVolume_) {
500         streamVolumeList.push_back(streamVolume.second);
501     }
502     std::sort(streamVolumeList.begin(), streamVolumeList.end(), [](StreamVolume &a, StreamVolume &b) {
503         return a.GetSessionId() < b.GetSessionId();
504     });
505     AppendFormat(dumpString, "\n  - audio stream volume size: %zu, his volume size: %zu, mon volume size: %zu\n",
506         streamVolumeList.size(), historyVolume_.size(), monitorVolume_.size());
507     for (auto &streamVolume : streamVolumeList) {
508         auto monVol = monitorVolume_.find(streamVolume.GetSessionId());
509         AppendFormat(dumpString, "  sessionId: %u ", streamVolume.GetSessionId());
510         AppendFormat(dumpString, "  streamType: %d ", streamVolume.GetStreamType());
511         AppendFormat(dumpString, "  streamUsage: %d ", streamVolume.GetStreamUsage());
512         AppendFormat(dumpString, "  appUid: %d ", streamVolume.GetAppUid());
513         AppendFormat(dumpString, "  appPid: %d ", streamVolume.GetAppPid());
514         AppendFormat(dumpString, "  volume: %f ", monVol != monitorVolume_.end() ? monVol->second.first : 0.0f);
515         AppendFormat(dumpString, "  volumeLevel: %d ",  monVol != monitorVolume_.end() ? monVol->second.second : 0);
516         AppendFormat(dumpString, "  volFactor: %f ", streamVolume.volume_);
517         AppendFormat(dumpString, "  duckFactor: %f ", streamVolume.duckFactor_);
518         AppendFormat(dumpString, "  powerFactor: %f ", streamVolume.lowPowerFactor_);
519         AppendFormat(dumpString, "  fadeBegin: %f ", streamVolume.fadeBegin_);
520         AppendFormat(dumpString, "  fadeEnd: %f \n", streamVolume.fadeEnd_);
521     }
522 }
523 
Monitor(uint32_t sessionId,bool isOutput)524 void AudioVolume::Monitor(uint32_t sessionId, bool isOutput)
525 {
526     std::shared_lock<std::shared_mutex> lock(volumeMutex_);
527     auto streamVolume = streamVolume_.find(sessionId);
528     if (streamVolume != streamVolume_.end()) {
529         auto monVol = monitorVolume_.find(sessionId);
530         std::shared_ptr<Media::MediaMonitor::EventBean> bean = std::make_shared<Media::MediaMonitor::EventBean>(
531             Media::MediaMonitor::AUDIO, Media::MediaMonitor::VOLUME_CHANGE,
532             Media::MediaMonitor::BEHAVIOR_EVENT);
533         bean->Add("ISOUTPUT", isOutput ? 1 : 0);
534         bean->Add("STREAMID", static_cast<int32_t>(sessionId));
535         bean->Add("APP_UID", streamVolume->second.GetAppUid());
536         bean->Add("APP_PID", streamVolume->second.GetAppPid());
537         bean->Add("STREAMTYPE", streamVolume->second.GetStreamType());
538         bean->Add("STREAM_TYPE", streamVolume->second.GetStreamUsage());
539         bean->Add("VOLUME", monVol != monitorVolume_.end() ? monVol->second.first : 0.0f);
540         bean->Add("SYSVOLUME", monVol != monitorVolume_.end() ? monVol->second.second : 0);
541         bean->Add("VOLUMEFACTOR", streamVolume->second.volume_);
542         bean->Add("POWERVOLUMEFACTOR", streamVolume->second.lowPowerFactor_);
543         Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
544     } else {
545         AUDIO_ERR_LOG("stream volume not exist, sessionId:%{public}u", sessionId);
546     }
547 }
548 
SetFadeoutState(uint32_t streamIndex,uint32_t fadeoutState)549 void AudioVolume::SetFadeoutState(uint32_t streamIndex, uint32_t fadeoutState)
550 {
551     std::unique_lock<std::shared_mutex> lock(fadoutMutex_);
552     fadeoutState_.insert_or_assign(streamIndex, fadeoutState);
553 }
554 
GetFadeoutState(uint32_t streamIndex)555 uint32_t AudioVolume::GetFadeoutState(uint32_t streamIndex)
556 {
557     std::shared_lock<std::shared_mutex> lock(fadoutMutex_);
558     auto it = fadeoutState_.find(streamIndex);
559     if (it != fadeoutState_.end()) { return it->second; }
560     AUDIO_WARNING_LOG("No such streamIndex in map!");
561     return INVALID_STATE;
562 }
563 
RemoveFadeoutState(uint32_t streamIndex)564 void AudioVolume::RemoveFadeoutState(uint32_t streamIndex)
565 {
566     std::unique_lock<std::shared_mutex> lock(fadoutMutex_);
567     fadeoutState_.erase(streamIndex);
568 }
569 
SetStopFadeoutState(uint32_t streamIndex,uint32_t fadeoutState)570 void AudioVolume::SetStopFadeoutState(uint32_t streamIndex, uint32_t fadeoutState)
571 {
572     std::unique_lock<std::shared_mutex> lock(fadoutMutex_);
573     stopFadeoutState_.insert_or_assign(streamIndex, fadeoutState);
574 }
575 
GetStopFadeoutState(uint32_t streamIndex)576 uint32_t AudioVolume::GetStopFadeoutState(uint32_t streamIndex)
577 {
578     std::shared_lock<std::shared_mutex> lock(fadoutMutex_);
579     auto it = stopFadeoutState_.find(streamIndex);
580     if (it != stopFadeoutState_.end()) {
581         return it->second;
582     }
583     AUDIO_WARNING_LOG("No such streamIndex in map!");
584     return INVALID_STATE;
585 }
586 
RemoveStopFadeoutState(uint32_t streamIndex)587 void AudioVolume::RemoveStopFadeoutState(uint32_t streamIndex)
588 {
589     std::unique_lock<std::shared_mutex> lock(fadoutMutex_);
590     stopFadeoutState_.erase(streamIndex);
591 }
592 
SetVgsVolumeSupported(bool isVgsSupported)593 void AudioVolume::SetVgsVolumeSupported(bool isVgsSupported)
594 {
595     isVgsVolumeSupported_ = isVgsSupported;
596 }
597 
IsVgsVolumeSupported() const598 bool AudioVolume::IsVgsVolumeSupported() const
599 {
600     return isVgsVolumeSupported_;
601 }
602 } // namespace AudioStandard
603 } // namespace OHOS
604 
605 #ifdef __cplusplus
606 extern "C" {
607 #endif
608 using namespace OHOS::AudioStandard;
609 
GetCurVolume(uint32_t sessionId,const char * streamType,const char * deviceClass)610 float GetCurVolume(uint32_t sessionId, const char *streamType, const char *deviceClass)
611 {
612     CHECK_AND_RETURN_RET_LOG(streamType != nullptr, 1.0f, "streamType is nullptr");
613     CHECK_AND_RETURN_RET_LOG(deviceClass != nullptr, 1.0f, "deviceClass is nullptr");
614     int32_t stream = AudioVolume::GetInstance()->ConvertStreamTypeStrToInt(streamType);
615     return AudioVolume::GetInstance()->GetVolume(sessionId, stream, deviceClass);
616 }
617 
GetStreamVolume(uint32_t sessionId)618 float GetStreamVolume(uint32_t sessionId)
619 {
620     return AudioVolume::GetInstance()->GetStreamVolume(sessionId);
621 }
622 
GetPreVolume(uint32_t sessionId)623 float GetPreVolume(uint32_t sessionId)
624 {
625     return AudioVolume::GetInstance()->GetHistoryVolume(sessionId);
626 }
627 
SetPreVolume(uint32_t sessionId,float volume)628 void SetPreVolume(uint32_t sessionId, float volume)
629 {
630     AudioVolume::GetInstance()->SetHistoryVolume(sessionId, volume);
631 }
632 
GetStreamVolumeFade(uint32_t sessionId,float * fadeBegin,float * fadeEnd)633 void GetStreamVolumeFade(uint32_t sessionId, float *fadeBegin, float *fadeEnd)
634 {
635     auto fade = AudioVolume::GetInstance()->GetStreamVolumeFade(sessionId);
636     *fadeBegin = fade.first;
637     *fadeEnd = fade.second;
638 }
639 
SetStreamVolumeFade(uint32_t sessionId,float fadeBegin,float fadeEnd)640 void SetStreamVolumeFade(uint32_t sessionId, float fadeBegin, float fadeEnd)
641 {
642     AudioVolume::GetInstance()->SetStreamVolumeFade(sessionId, fadeBegin, fadeEnd);
643 }
644 
IsSameVolume(float x,float y)645 bool IsSameVolume(float x, float y)
646 {
647     return AudioVolume::GetInstance()->IsSameVolume(x, y);
648 }
649 
MonitorVolume(uint32_t sessionId,bool isOutput)650 void MonitorVolume(uint32_t sessionId, bool isOutput)
651 {
652     AudioVolume::GetInstance()->Monitor(sessionId, isOutput);
653 }
654 
SetFadeoutState(uint32_t streamIndex,uint32_t fadeoutState)655 void SetFadeoutState(uint32_t streamIndex, uint32_t fadeoutState)
656 {
657     AudioVolume::GetInstance()->SetFadeoutState(streamIndex, fadeoutState);
658 }
659 
GetFadeoutState(uint32_t streamIndex)660 uint32_t GetFadeoutState(uint32_t streamIndex)
661 {
662     return AudioVolume::GetInstance()->GetFadeoutState(streamIndex);
663 }
664 
GetStopFadeoutState(uint32_t streamIndex)665 uint32_t GetStopFadeoutState(uint32_t streamIndex)
666 {
667     return AudioVolume::GetInstance()->GetStopFadeoutState(streamIndex);
668 }
669 
RemoveStopFadeoutState(uint32_t streamIndex)670 void RemoveStopFadeoutState(uint32_t streamIndex)
671 {
672     AudioVolume::GetInstance()->RemoveStopFadeoutState(streamIndex);
673 }
674 
GetSimpleBufferAvg(uint8_t * buffer,int32_t length)675 int32_t GetSimpleBufferAvg(uint8_t *buffer, int32_t length)
676 {
677     if (length <= 0) {
678         return -1;
679     }
680     int32_t sum = std::accumulate(buffer, buffer + length, 0);
681     return sum / length;
682 }
683 
GetFadeStrategy(uint64_t expectedPlaybackDurationMs)684 FadeStrategy GetFadeStrategy(uint64_t expectedPlaybackDurationMs)
685 {
686     // 0 is default; duration > 40ms do default fade
687     if (expectedPlaybackDurationMs == 0 || expectedPlaybackDurationMs > DURATION_TIME_DEFAULT) {
688         return FADE_STRATEGY_DEFAULT;
689     }
690 
691     // duration <= 10 ms no fade
692     if (expectedPlaybackDurationMs <= DURATION_TIME_SHORT && expectedPlaybackDurationMs > 0) {
693         return FADE_STRATEGY_NONE;
694     }
695 
696     // duration > 10ms && duration <= 40ms do 5ms fade
697     if (expectedPlaybackDurationMs <= DURATION_TIME_DEFAULT && expectedPlaybackDurationMs > DURATION_TIME_SHORT) {
698         return FADE_STRATEGY_SHORTER;
699     }
700 
701     return FADE_STRATEGY_DEFAULT;
702 }
703 #ifdef __cplusplus
704 }
705 #endif