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