1 /*
2 * Copyright (c) 2025 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 #include "OHAudioVolumeManager.h"
17 #include <set>
18
19 #include "audio_common_log.h"
20 #include "audio_system_manager.h"
21 #include "audio_common_utils.h"
22
23 namespace {
24 const std::set<OH_AudioStream_Usage> VALID_OH_STREAM_USAGES = {
25 AUDIOSTREAM_USAGE_UNKNOWN,
26 AUDIOSTREAM_USAGE_MUSIC,
27 AUDIOSTREAM_USAGE_VOICE_COMMUNICATION,
28 AUDIOSTREAM_USAGE_VOICE_ASSISTANT,
29 AUDIOSTREAM_USAGE_ALARM,
30 AUDIOSTREAM_USAGE_VOICE_MESSAGE,
31 AUDIOSTREAM_USAGE_RINGTONE,
32 AUDIOSTREAM_USAGE_NOTIFICATION,
33 AUDIOSTREAM_USAGE_ACCESSIBILITY,
34 AUDIOSTREAM_USAGE_MOVIE,
35 AUDIOSTREAM_USAGE_GAME,
36 AUDIOSTREAM_USAGE_AUDIOBOOK,
37 AUDIOSTREAM_USAGE_NAVIGATION,
38 AUDIOSTREAM_USAGE_VIDEO_COMMUNICATION
39 };
40
41 const std::set<OH_AudioRingerMode> VALID_OH_RINGER_MODES = {
42 AUDIO_RINGER_MODE_SILENT,
43 AUDIO_RINGER_MODE_VIBRATE,
44 AUDIO_RINGER_MODE_NORMAL
45 };
46 }
47
48 using OHOS::AudioStandard::OHAudioVolumeManager;
49 using OHOS::AudioStandard::StreamUsage;
50
OH_AudioManager_GetAudioVolumeManager(OH_AudioVolumeManager ** volumeManager)51 OH_AudioCommon_Result OH_AudioManager_GetAudioVolumeManager(
52 OH_AudioVolumeManager **volumeManager)
53 {
54 if (volumeManager == nullptr) {
55 AUDIO_ERR_LOG("invalid OH_AudioVolumeManager");
56 return AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM;
57 }
58
59 OHAudioVolumeManager *manager = OHAudioVolumeManager::GetInstance();
60 *volumeManager = (OH_AudioVolumeManager *)manager;
61 return AUDIOCOMMON_RESULT_SUCCESS;
62 }
63
OH_AudioVolumeManager_GetMaxVolumeByUsage(OH_AudioVolumeManager * volumeManager,OH_AudioStream_Usage usage,int32_t * maxVolumeLevel)64 OH_AudioCommon_Result OH_AudioVolumeManager_GetMaxVolumeByUsage(OH_AudioVolumeManager *volumeManager,
65 OH_AudioStream_Usage usage, int32_t *maxVolumeLevel)
66 {
67 if (volumeManager == nullptr || !VALID_OH_STREAM_USAGES.count(usage) || maxVolumeLevel == nullptr) {
68 AUDIO_ERR_LOG("invalid volumeManager or usage or maxVolumeLevel");
69 return AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM;
70 }
71
72 OHAudioVolumeManager *ohAudioVolumeManager = (OHAudioVolumeManager*)volumeManager;
73 StreamUsage streamUsage = static_cast<StreamUsage>(usage);
74 int32_t volumeLevel = ohAudioVolumeManager->GetMaxVolumeByUsage(streamUsage);
75 if (volumeLevel < 0) {
76 AUDIO_ERR_LOG("GetMaxVolumeByUsage failed");
77 return AUDIOCOMMON_RESULT_ERROR_SYSTEM;
78 }
79 *maxVolumeLevel = volumeLevel;
80 return AUDIOCOMMON_RESULT_SUCCESS;
81 }
82
OH_AudioVolumeManager_GetMinVolumeByUsage(OH_AudioVolumeManager * volumeManager,OH_AudioStream_Usage usage,int32_t * minVolumeLevel)83 OH_AudioCommon_Result OH_AudioVolumeManager_GetMinVolumeByUsage(OH_AudioVolumeManager *volumeManager,
84 OH_AudioStream_Usage usage, int32_t *minVolumeLevel)
85 {
86 if (volumeManager == nullptr || !VALID_OH_STREAM_USAGES.count(usage) || minVolumeLevel == nullptr) {
87 AUDIO_ERR_LOG("invalid volumeManager or usage or maxVolumeLevel");
88 return AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM;
89 }
90
91 OHAudioVolumeManager *ohAudioVolumeManager = (OHAudioVolumeManager*)volumeManager;
92 StreamUsage streamUsage = static_cast<StreamUsage>(usage);
93 int32_t volumeLevel = ohAudioVolumeManager->GetMinVolumeByUsage(streamUsage);
94 if (volumeLevel < 0) {
95 AUDIO_ERR_LOG("GetMinVolumeByUsage failed");
96 return AUDIOCOMMON_RESULT_ERROR_SYSTEM;
97 }
98 *minVolumeLevel = volumeLevel;
99 return AUDIOCOMMON_RESULT_SUCCESS;
100 }
101
OH_AudioVolumeManager_GetVolumeByUsage(OH_AudioVolumeManager * volumeManager,OH_AudioStream_Usage usage,int32_t * volumeLevel)102 OH_AudioCommon_Result OH_AudioVolumeManager_GetVolumeByUsage(OH_AudioVolumeManager *volumeManager,
103 OH_AudioStream_Usage usage, int32_t *volumeLevel)
104 {
105 if (volumeManager == nullptr || !VALID_OH_STREAM_USAGES.count(usage) || volumeLevel == nullptr) {
106 AUDIO_ERR_LOG("invalid volumeManager or usage or maxVolumeLevel");
107 return AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM;
108 }
109
110 OHAudioVolumeManager *ohAudioVolumeManager = (OHAudioVolumeManager*)volumeManager;
111 StreamUsage streamUsage = static_cast<StreamUsage>(usage);
112 int32_t volume = ohAudioVolumeManager->GetVolumeByUsage(streamUsage);
113 if (volume < 0) {
114 AUDIO_ERR_LOG("GetVolumeByUsage failed");
115 return AUDIOCOMMON_RESULT_ERROR_SYSTEM;
116 }
117 *volumeLevel = volume;
118 return AUDIOCOMMON_RESULT_SUCCESS;
119 }
120
OH_AudioVolumeManager_IsMuteByUsage(OH_AudioVolumeManager * volumeManager,OH_AudioStream_Usage usage,bool * muted)121 OH_AudioCommon_Result OH_AudioVolumeManager_IsMuteByUsage(OH_AudioVolumeManager *volumeManager,
122 OH_AudioStream_Usage usage, bool *muted)
123 {
124 if (volumeManager == nullptr || !VALID_OH_STREAM_USAGES.count(usage) || muted == nullptr) {
125 AUDIO_ERR_LOG("invalid volumeManager or usage or muted");
126 return AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM;
127 }
128
129 OHAudioVolumeManager *ohAudioVolumeManager = (OHAudioVolumeManager*)volumeManager;
130 StreamUsage streamUsage = static_cast<StreamUsage>(usage);
131 int32_t result = ohAudioVolumeManager->IsMuteByUsage(streamUsage, *muted);
132 if (result < 0) {
133 AUDIO_ERR_LOG("IsMuteByUsage failed");
134 return AUDIOCOMMON_RESULT_ERROR_SYSTEM;
135 }
136 return AUDIOCOMMON_RESULT_SUCCESS;
137 }
138
OH_AudioVolumeManager_RegisterStreamVolumeChangeCallback(OH_AudioVolumeManager * volumeManager,OH_AudioStream_Usage usage,OH_AudioVolumeManager_OnStreamVolumeChangeCallback callback,void * userData)139 OH_AudioCommon_Result OH_AudioVolumeManager_RegisterStreamVolumeChangeCallback(
140 OH_AudioVolumeManager *volumeManager, OH_AudioStream_Usage usage,
141 OH_AudioVolumeManager_OnStreamVolumeChangeCallback callback, void *userData)
142 {
143 if (volumeManager == nullptr || !VALID_OH_STREAM_USAGES.count(usage) || callback == nullptr) {
144 AUDIO_ERR_LOG("invalid volumeManager or usage or callback");
145 return AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM;
146 }
147
148 OHAudioVolumeManager *ohAudioVolumeManager = (OHAudioVolumeManager*)volumeManager;
149 StreamUsage streamUsage = static_cast<StreamUsage>(usage);
150 int32_t result = ohAudioVolumeManager->SetStreamVolumeChangeCallback(callback, streamUsage, userData);
151 return static_cast<OH_AudioCommon_Result>(result);
152 }
153
OH_AudioVolumeManager_UnregisterStreamVolumeChangeCallback(OH_AudioVolumeManager * volumeManager,OH_AudioVolumeManager_OnStreamVolumeChangeCallback callback)154 OH_AudioCommon_Result OH_AudioVolumeManager_UnregisterStreamVolumeChangeCallback(
155 OH_AudioVolumeManager *volumeManager,
156 OH_AudioVolumeManager_OnStreamVolumeChangeCallback callback)
157 {
158 if (volumeManager == nullptr || callback == nullptr) {
159 AUDIO_ERR_LOG("invalid volumeManager or callback");
160 return AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM;
161 }
162
163 OHAudioVolumeManager *ohAudioVolumeManager = (OHAudioVolumeManager*)volumeManager;
164 int32_t result = ohAudioVolumeManager->UnsetStreamVolumeChangeCallback(callback);
165 return static_cast<OH_AudioCommon_Result>(result);
166 }
167
OH_AudioVolumeManager_GetRingerMode(OH_AudioVolumeManager * volumeManager,OH_AudioRingerMode * ringerMode)168 OH_AudioCommon_Result OH_AudioVolumeManager_GetRingerMode(OH_AudioVolumeManager *volumeManager,
169 OH_AudioRingerMode *ringerMode)
170 {
171 if (volumeManager == nullptr || ringerMode == nullptr) {
172 AUDIO_ERR_LOG("invalid volumeManager or ringerMode");
173 return AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM;
174 }
175
176 OHAudioVolumeManager *ohAudioVolumeManager = (OHAudioVolumeManager*)volumeManager;
177 int32_t result = ohAudioVolumeManager->GetRingerMode();
178 if (result < 0 || VALID_OH_RINGER_MODES.count(static_cast<OH_AudioRingerMode>(result)) == 0) {
179 AUDIO_ERR_LOG("IsMuteByUsage failed");
180 return AUDIOCOMMON_RESULT_ERROR_SYSTEM;
181 }
182 *ringerMode = static_cast<OH_AudioRingerMode>(result);
183 return AUDIOCOMMON_RESULT_SUCCESS;
184 }
185
OH_AudioVolumeManager_RegisterRingerModeChangeCallback(OH_AudioVolumeManager * volumeManager,OH_AudioVolumeManager_OnRingerModeChangeCallback callback,void * userData)186 OH_AudioCommon_Result OH_AudioVolumeManager_RegisterRingerModeChangeCallback(
187 OH_AudioVolumeManager *volumeManager,
188 OH_AudioVolumeManager_OnRingerModeChangeCallback callback, void *userData)
189 {
190 if (volumeManager == nullptr || callback == nullptr) {
191 AUDIO_ERR_LOG("invalid volumeManager or callback");
192 return AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM;
193 }
194
195 OHAudioVolumeManager *ohAudioVolumeManager = (OHAudioVolumeManager*)volumeManager;
196 int32_t result = ohAudioVolumeManager->SetAudioRingerModeChangeCallback(callback, userData);
197 return static_cast<OH_AudioCommon_Result>(result);
198 }
199
OH_AudioVolumeManager_UnregisterRingerModeChangeCallback(OH_AudioVolumeManager * volumeManager,OH_AudioVolumeManager_OnRingerModeChangeCallback callback)200 OH_AudioCommon_Result OH_AudioVolumeManager_UnregisterRingerModeChangeCallback(
201 OH_AudioVolumeManager *volumeManager,
202 OH_AudioVolumeManager_OnRingerModeChangeCallback callback)
203 {
204 if (volumeManager == nullptr || callback == nullptr) {
205 AUDIO_ERR_LOG("invalid volumeManager or callback");
206 return AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM;
207 }
208
209 OHAudioVolumeManager *ohAudioVolumeManager = (OHAudioVolumeManager*)volumeManager;
210 int32_t result = ohAudioVolumeManager->UnsetAudioRingerModeChangeCallback(callback);
211 return static_cast<OH_AudioCommon_Result>(result);
212 }
213
214 namespace OHOS {
215 namespace AudioStandard {
OnStreamVolumeChange(StreamVolumeEvent streamVolumeEvent)216 void OHStreamVolumeChangeCallback::OnStreamVolumeChange(StreamVolumeEvent streamVolumeEvent)
217 {
218 CHECK_AND_RETURN_LOG(callback_ != nullptr, "failed, pointer to the fuction is nullptr");
219 if (usage_ != streamVolumeEvent.streamUsage) {
220 AUDIO_ERR_LOG("usage is not equal");
221 return;
222 }
223 callback_(userData_, static_cast<OH_AudioStream_Usage>(usage_), streamVolumeEvent.volume,
224 streamVolumeEvent.updateUi);
225 }
226
OnRingerModeUpdated(const AudioRingerMode & ringerMode)227 void OHAudioRingerModeCallback::OnRingerModeUpdated(const AudioRingerMode &ringerMode)
228 {
229 CHECK_AND_RETURN_LOG(callback_ != nullptr, "failed, pointer to the fuction is nullptr");
230 callback_(userData_, static_cast<OH_AudioRingerMode>(ringerMode));
231 }
232
GetInstance()233 OHAudioVolumeManager *OHAudioVolumeManager::GetInstance()
234 {
235 static OHAudioVolumeManager instance;
236 return &instance;
237 }
238
OHAudioVolumeManager()239 OHAudioVolumeManager::OHAudioVolumeManager()
240 {
241 audioSystemManager_ = AudioSystemManager::GetInstance();
242 CHECK_AND_RETURN_LOG(audioSystemManager_ != nullptr, "failed, audioSystemManager_ is nullptr");
243 audioGroupManager_ = audioSystemManager_->GetGroupManager(DEFAULT_VOLUME_GROUP_ID);
244 CHECK_AND_RETURN_LOG(audioGroupManager_ != nullptr, "failed, audioGroupManager_ is nullptr");
245 }
246
GetMaxVolumeByUsage(StreamUsage streamUsage)247 int32_t OHAudioVolumeManager::GetMaxVolumeByUsage(StreamUsage streamUsage)
248 {
249 CHECK_AND_RETURN_RET_LOG(audioSystemManager_ != nullptr, AUDIOCOMMON_RESULT_ERROR_SYSTEM,
250 "failed, audioSystemManager_ is nullptr");
251 return audioSystemManager_->GetMaxVolumeByUsage(streamUsage);
252 }
253
GetMinVolumeByUsage(StreamUsage streamUsage)254 int32_t OHAudioVolumeManager::GetMinVolumeByUsage(StreamUsage streamUsage)
255 {
256 CHECK_AND_RETURN_RET_LOG(audioSystemManager_ != nullptr, AUDIOCOMMON_RESULT_ERROR_SYSTEM,
257 "failed, audioSystemManager_ is nullptr");
258 return audioSystemManager_->GetMinVolumeByUsage(streamUsage);
259 }
260
GetVolumeByUsage(StreamUsage streamUsage)261 int32_t OHAudioVolumeManager::GetVolumeByUsage(StreamUsage streamUsage)
262 {
263 CHECK_AND_RETURN_RET_LOG(audioSystemManager_ != nullptr, AUDIOCOMMON_RESULT_ERROR_SYSTEM,
264 "failed, audioSystemManager_ is nullptr");
265 return audioSystemManager_->GetVolumeByUsage(streamUsage);
266 }
267
IsMuteByUsage(StreamUsage streamUsage,bool & isMute)268 int32_t OHAudioVolumeManager::IsMuteByUsage(StreamUsage streamUsage, bool &isMute)
269 {
270 CHECK_AND_RETURN_RET_LOG(audioSystemManager_ != nullptr, AUDIOCOMMON_RESULT_ERROR_SYSTEM,
271 "failed, audioSystemManager_ is nullptr");
272 return audioSystemManager_->IsStreamMuteByUsage(streamUsage, isMute);
273 }
274
GetRingerMode()275 int32_t OHAudioVolumeManager::GetRingerMode()
276 {
277 CHECK_AND_RETURN_RET_LOG(audioGroupManager_ != nullptr, AUDIOCOMMON_RESULT_ERROR_SYSTEM,
278 "failed, audioGroupManager_ is nullptr");
279 return (int32_t)audioGroupManager_->GetRingerMode();
280 }
281
SetStreamVolumeChangeCallback(OH_AudioVolumeManager_OnStreamVolumeChangeCallback callback,StreamUsage streamUsage,void * userData)282 int32_t OHAudioVolumeManager::SetStreamVolumeChangeCallback(
283 OH_AudioVolumeManager_OnStreamVolumeChangeCallback callback, StreamUsage streamUsage, void *userData)
284 {
285 CHECK_AND_RETURN_RET_LOG(audioSystemManager_ != nullptr, AUDIOCOMMON_RESULT_ERROR_SYSTEM,
286 "failed, audioSystemManager_ is nullptr");
287 if (callback == nullptr) {
288 AUDIO_ERR_LOG("invalid callback");
289 return AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM;
290 }
291
292 std::lock_guard<std::mutex> lock(streamVolumeCbMutex_);
293 if (streamVolumeCallbacks_.count(callback)) {
294 if (streamVolumeCallbacks_[callback].first == streamUsage) {
295 AUDIO_INFO_LOG("callback already registered");
296 return AUDIOCOMMON_RESULT_SUCCESS;
297 } else {
298 AUDIO_ERR_LOG("callback already registered for different streamUsage:%{public}d",
299 streamVolumeCallbacks_[callback].first);
300 return AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM;
301 }
302 }
303
304 streamUsage = (streamUsage == StreamUsage::STREAM_USAGE_UNKNOWN) ? StreamUsage::STREAM_USAGE_MUSIC : streamUsage;
305 auto ohAudioVolumeCallback = std::make_shared<OHStreamVolumeChangeCallback>(callback, streamUsage, userData);
306 CHECK_AND_RETURN_RET_LOG(ohAudioVolumeCallback != nullptr, AUDIOCOMMON_RESULT_ERROR_SYSTEM,
307 "Failed to create callback!");
308
309 int32_t result = audioSystemManager_->RegisterStreamVolumeChangeCallback(getpid(), { streamUsage },
310 ohAudioVolumeCallback);
311 if (result == AUDIOCOMMON_RESULT_SUCCESS) {
312 streamVolumeCallbacks_[callback] = {streamUsage, ohAudioVolumeCallback};
313 }
314 return result == AUDIOCOMMON_RESULT_SUCCESS ? AUDIOCOMMON_RESULT_SUCCESS : AUDIOCOMMON_RESULT_ERROR_SYSTEM;
315 }
316
UnsetStreamVolumeChangeCallback(OH_AudioVolumeManager_OnStreamVolumeChangeCallback callback)317 int32_t OHAudioVolumeManager::UnsetStreamVolumeChangeCallback(
318 OH_AudioVolumeManager_OnStreamVolumeChangeCallback callback)
319 {
320 CHECK_AND_RETURN_RET_LOG(audioSystemManager_ != nullptr, AUDIOCOMMON_RESULT_ERROR_SYSTEM,
321 "failed, audioSystemManager_ is nullptr");
322
323 std::lock_guard<std::mutex> lock(streamVolumeCbMutex_);
324 if (callback == nullptr || !streamVolumeCallbacks_.count(callback)) {
325 AUDIO_ERR_LOG("invalid callback or callback not registered");
326 return AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM;
327 }
328
329 int32_t result = audioSystemManager_->UnregisterStreamVolumeChangeCallback(getpid(),
330 streamVolumeCallbacks_[callback].second);
331 if (result == AUDIOCOMMON_RESULT_SUCCESS) {
332 streamVolumeCallbacks_.erase(callback);
333 }
334 return result == AUDIOCOMMON_RESULT_SUCCESS ? AUDIOCOMMON_RESULT_SUCCESS : AUDIOCOMMON_RESULT_ERROR_SYSTEM;
335 }
336
SetAudioRingerModeChangeCallback(OH_AudioVolumeManager_OnRingerModeChangeCallback callback,void * userData)337 int32_t OHAudioVolumeManager::SetAudioRingerModeChangeCallback(
338 OH_AudioVolumeManager_OnRingerModeChangeCallback callback, void *userData)
339 {
340 CHECK_AND_RETURN_RET_LOG(audioGroupManager_ != nullptr, AUDIOCOMMON_RESULT_ERROR_SYSTEM,
341 "failed, audioGroupManager_ is nullptr");
342 if (callback == nullptr) {
343 AUDIO_ERR_LOG("invalid callback");
344 return AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM;
345 }
346
347 std::lock_guard<std::mutex> lock(ringerModeCbMutex_);
348 if (ringerModeCallbacks_.count(callback)) {
349 AUDIO_INFO_LOG("callback already registered");
350 return AUDIOCOMMON_RESULT_SUCCESS;
351 }
352
353 auto ohAudioRingerModeCallback = std::make_shared<OHAudioRingerModeCallback>(callback, userData);
354 CHECK_AND_RETURN_RET_LOG(ohAudioRingerModeCallback != nullptr, AUDIOCOMMON_RESULT_ERROR_SYSTEM,
355 "Failed to create callback!");
356
357 int32_t result = audioGroupManager_->SetRingerModeCallback(getpid(), ohAudioRingerModeCallback);
358 if (result == AUDIOCOMMON_RESULT_SUCCESS) {
359 ringerModeCallbacks_.emplace(callback, ohAudioRingerModeCallback);
360 }
361 return result == AUDIOCOMMON_RESULT_SUCCESS ? AUDIOCOMMON_RESULT_SUCCESS : AUDIOCOMMON_RESULT_ERROR_SYSTEM;
362 }
363
UnsetAudioRingerModeChangeCallback(OH_AudioVolumeManager_OnRingerModeChangeCallback callback)364 int32_t OHAudioVolumeManager::UnsetAudioRingerModeChangeCallback(
365 OH_AudioVolumeManager_OnRingerModeChangeCallback callback)
366 {
367 CHECK_AND_RETURN_RET_LOG(audioGroupManager_ != nullptr, AUDIOCOMMON_RESULT_ERROR_SYSTEM,
368 "failed, audioGroupManager_ is nullptr");
369 std::lock_guard<std::mutex> lock(ringerModeCbMutex_);
370 if (callback == nullptr || !ringerModeCallbacks_.count(callback)) {
371 AUDIO_ERR_LOG("invalid callback or callback not registered");
372 return AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM;
373 }
374
375 int32_t result = audioGroupManager_->UnsetRingerModeCallback(getpid(), ringerModeCallbacks_[callback]);
376 if (result == AUDIOCOMMON_RESULT_SUCCESS) {
377 ringerModeCallbacks_.erase(callback);
378 }
379 return result == AUDIOCOMMON_RESULT_SUCCESS ? AUDIOCOMMON_RESULT_SUCCESS : AUDIOCOMMON_RESULT_ERROR_SYSTEM;
380 }
381 } // namespace AudioStandard
382 } // namespace OHOS