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