1 /*
2 * Copyright (c) 2022 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 "audio_errors.h"
17 #include "audio_manager_proxy.h"
18 #include "audio_policy_manager.h"
19 #include "audio_log.h"
20 #include "iservice_registry.h"
21 #include "system_ability_definition.h"
22
23 #include "audio_group_manager.h"
24
25 namespace OHOS {
26 namespace AudioStandard {
27 static sptr<IStandardAudioService> g_sProxy = nullptr;
AudioGroupManager(int32_t groupId)28 AudioGroupManager::AudioGroupManager(int32_t groupId) : groupId_(groupId)
29 {
30 }
~AudioGroupManager()31 AudioGroupManager::~AudioGroupManager()
32 {
33 AUDIO_DEBUG_LOG("AudioGroupManager start");
34 if (cbClientId_ != -1) {
35 UnsetRingerModeCallback(cbClientId_);
36 }
37 }
38
MapVolumeToHDI(int32_t volume)39 float AudioGroupManager::MapVolumeToHDI(int32_t volume)
40 {
41 float value = (float)volume / MAX_VOLUME_LEVEL;
42 float roundValue = (int)(value * CONST_FACTOR);
43
44 return (float)roundValue / CONST_FACTOR;
45 }
46
MapVolumeFromHDI(float volume)47 int32_t AudioGroupManager::MapVolumeFromHDI(float volume)
48 {
49 float value = (float)volume * MAX_VOLUME_LEVEL;
50 return nearbyint(value);
51 }
52
SetVolume(AudioVolumeType volumeType,int32_t volume)53 int32_t AudioGroupManager::SetVolume(AudioVolumeType volumeType, int32_t volume)
54 {
55 if (connectType_ == CONNECT_TYPE_DISTRIBUTED) {
56 std::string condition = "EVENT_TYPE=1;VOLUME_GROUP_ID=" + std::to_string(groupId_) + ";AUDIO_VOLUME_TYPE="
57 + std::to_string(volumeType) + ";";
58 std::string value = std::to_string(volume);
59 g_sProxy->SetAudioParameter(netWorkId_, AudioParamKey::VOLUME, condition, value);
60 return SUCCESS;
61 }
62
63 AUDIO_DEBUG_LOG("AudioSystemManager SetVolume volumeType=%{public}d ", volumeType);
64
65 /* Validate and return INVALID_PARAMS error */
66 if ((volume < MIN_VOLUME_LEVEL) || (volume > MAX_VOLUME_LEVEL)) {
67 AUDIO_ERR_LOG("Invalid Volume Input!");
68 return ERR_INVALID_PARAM;
69 }
70
71 switch (volumeType) {
72 case STREAM_MUSIC:
73 case STREAM_RING:
74 case STREAM_NOTIFICATION:
75 case STREAM_VOICE_CALL:
76 case STREAM_VOICE_ASSISTANT:
77 case STREAM_ALL:
78 break;
79 default:
80 AUDIO_ERR_LOG("SetVolume volumeType=%{public}d not supported", volumeType);
81 return ERR_NOT_SUPPORTED;
82 }
83
84 /* Call Audio Policy SetStreamVolume */
85 AudioStreamType StreamVolType = (AudioStreamType)volumeType;
86 float volumeToHdi = MapVolumeToHDI(volume);
87
88 if (volumeType == STREAM_ALL) {
89 for (auto audioVolumeType : GET_STREAM_ALL_VOLUME_TYPES) {
90 StreamVolType = (AudioStreamType)audioVolumeType;
91 int32_t setResult = AudioPolicyManager::GetInstance().SetStreamVolume(StreamVolType, volumeToHdi);
92 AUDIO_DEBUG_LOG("SetVolume of STREAM_ALL, volumeType=%{public}d ", StreamVolType);
93 if (setResult != SUCCESS) {
94 return setResult;
95 }
96 }
97 return SUCCESS;
98 }
99
100 return AudioPolicyManager::GetInstance().SetStreamVolume(StreamVolType, volumeToHdi);
101 }
102
GetVolume(AudioVolumeType volumeType)103 int32_t AudioGroupManager::GetVolume(AudioVolumeType volumeType)
104 {
105 if (connectType_ == CONNECT_TYPE_DISTRIBUTED) {
106 std::string condition = "EVENT_TYPE=1;VOLUME_GROUP_ID=" + std::to_string(groupId_) + ";AUDIO_VOLUME_TYPE="
107 + std::to_string(volumeType) + ";";
108 std::string value = g_sProxy->GetAudioParameter(netWorkId_, AudioParamKey::VOLUME, condition);
109 if (value.empty()) {
110 AUDIO_ERR_LOG("[AudioGroupManger]: invalid value %{public}s", value.c_str());
111 return 0;
112 }
113 return std::stoi(value);
114 }
115 switch (volumeType) {
116 case STREAM_MUSIC:
117 case STREAM_RING:
118 case STREAM_NOTIFICATION:
119 case STREAM_VOICE_CALL:
120 case STREAM_VOICE_ASSISTANT:
121 case STREAM_ALL:
122 break;
123 default:
124 AUDIO_ERR_LOG("GetVolume volumeType=%{public}d not supported", volumeType);
125 return (float)ERR_NOT_SUPPORTED;
126 }
127
128 if (volumeType == STREAM_ALL) {
129 volumeType = STREAM_MUSIC;
130 AUDIO_DEBUG_LOG("GetVolume of STREAM_ALL for volumeType=%{public}d ", volumeType);
131 }
132
133 /* Call Audio Policy SetStreamMute */
134 AudioStreamType StreamVolType = (AudioStreamType)volumeType;
135 float volumeFromHdi = AudioPolicyManager::GetInstance().GetStreamVolume(StreamVolType);
136
137 return MapVolumeFromHDI(volumeFromHdi);
138 }
139
GetMaxVolume(AudioVolumeType volumeType)140 int32_t AudioGroupManager::GetMaxVolume(AudioVolumeType volumeType)
141 {
142 if (!IsAlived()) {
143 CHECK_AND_RETURN_RET_LOG(g_sProxy != nullptr, ERR_OPERATION_FAILED, "GetMaxVolume service unavailable");
144 }
145 if (connectType_ == CONNECT_TYPE_DISTRIBUTED) {
146 std::string condition = "EVENT_TYPE=3;VOLUME_GROUP_ID=" + std::to_string(groupId_) + ";AUDIO_VOLUME_TYPE=" +
147 std::to_string(volumeType) + ";";
148 std::string value = g_sProxy->GetAudioParameter(netWorkId_, AudioParamKey::VOLUME, condition);
149 if (value.empty()) {
150 AUDIO_ERR_LOG("[AudioGroupManger]: invalid value %{public}s", value.c_str());
151 return 0;
152 }
153 return std::stoi(value);
154 }
155
156 if (volumeType == STREAM_ALL) {
157 volumeType = STREAM_MUSIC;
158 }
159 return g_sProxy->GetMaxVolume(volumeType);
160 }
161
GetMinVolume(AudioVolumeType volumeType)162 int32_t AudioGroupManager::GetMinVolume(AudioVolumeType volumeType)
163 {
164 if (!IsAlived()) {
165 CHECK_AND_RETURN_RET_LOG(g_sProxy != nullptr, ERR_OPERATION_FAILED, "GetMinVolume service unavailable");
166 }
167 if (connectType_ == CONNECT_TYPE_DISTRIBUTED) {
168 std::string condition = "EVENT_TYPE=2;VOLUME_GROUP_ID=" + std::to_string(groupId_) + ";AUDIO_VOLUME_TYPE" +
169 std::to_string(volumeType) + ";";
170 std::string value = g_sProxy->GetAudioParameter(netWorkId_, AudioParamKey::VOLUME, condition);
171 if (value.empty()) {
172 AUDIO_ERR_LOG("[AudioGroupManger]: invalid value %{public}s", value.c_str());
173 return 0;
174 }
175 return std::stoi(value);
176 }
177
178 if (volumeType == STREAM_ALL) {
179 volumeType = STREAM_MUSIC;
180 }
181 return g_sProxy->GetMinVolume(volumeType);
182 }
183
SetMute(AudioVolumeType volumeType,bool mute)184 int32_t AudioGroupManager::SetMute(AudioVolumeType volumeType, bool mute)
185 {
186 if (connectType_ == CONNECT_TYPE_DISTRIBUTED) {
187 std::string conditon = "EVENT_TYPE=4;VOLUME_GROUP_ID=" + std::to_string(groupId_) + ";AUDIO_VOLUME_TYPE="
188 + std::to_string(volumeType) + ";";
189 std::string value = mute ? "1" : "0";
190 g_sProxy->SetAudioParameter(netWorkId_, AudioParamKey::VOLUME, conditon, value);
191 return SUCCESS;
192 }
193
194 AUDIO_DEBUG_LOG("AudioSystemManager SetMute for volumeType=%{public}d", volumeType);
195 switch (volumeType) {
196 case STREAM_MUSIC:
197 case STREAM_RING:
198 case STREAM_NOTIFICATION:
199 case STREAM_VOICE_CALL:
200 case STREAM_VOICE_ASSISTANT:
201 case STREAM_ALL:
202 break;
203 default:
204 AUDIO_ERR_LOG("SetMute volumeType=%{public}d not supported", volumeType);
205 return ERR_NOT_SUPPORTED;
206 }
207
208 /* Call Audio Policy SetStreamMute */
209 AudioStreamType StreamVolType = (AudioStreamType)volumeType;
210
211 if (volumeType == STREAM_ALL) {
212 for (auto audioVolumeType : GET_STREAM_ALL_VOLUME_TYPES) {
213 StreamVolType = (AudioStreamType)audioVolumeType;
214 int32_t setResult = AudioPolicyManager::GetInstance().SetStreamMute(StreamVolType, mute);
215 AUDIO_DEBUG_LOG("SetMute of STREAM_ALL for volumeType=%{public}d ", StreamVolType);
216 if (setResult != SUCCESS) {
217 return setResult;
218 }
219 }
220 return SUCCESS;
221 }
222
223 return AudioPolicyManager::GetInstance().SetStreamMute(StreamVolType, mute);
224 }
225
IsStreamMute(AudioVolumeType volumeType)226 bool AudioGroupManager::IsStreamMute(AudioVolumeType volumeType)
227 {
228 AUDIO_DEBUG_LOG("AudioSystemManager::GetMute Client");
229 if (connectType_ == CONNECT_TYPE_DISTRIBUTED) {
230 std::string condition = "EVENT_TYPE=4;VOLUME_GROUP_ID=" + std::to_string(groupId_) + ";AUDIO_VOLUME_TYPE="
231 + std::to_string(volumeType) + ";";
232 std::string ret = g_sProxy->GetAudioParameter(netWorkId_, AudioParamKey::VOLUME, condition);
233
234 return ret == "1" ? true : false;
235 }
236
237 switch (volumeType) {
238 case STREAM_MUSIC:
239 case STREAM_RING:
240 case STREAM_NOTIFICATION:
241 case STREAM_VOICE_CALL:
242 case STREAM_VOICE_ASSISTANT:
243 case STREAM_ALL:
244 break;
245 default:
246 AUDIO_ERR_LOG("IsStreamMute volumeType=%{public}d not supported", volumeType);
247 return false;
248 }
249
250 if (volumeType == STREAM_ALL) {
251 volumeType = STREAM_MUSIC;
252 }
253
254 /* Call Audio Policy SetStreamVolume */
255 AudioStreamType StreamVolType = (AudioStreamType)volumeType;
256 return AudioPolicyManager::GetInstance().GetStreamMute(StreamVolType);
257 }
258
Init()259 int32_t AudioGroupManager::Init()
260 {
261 // init networkId_
262 int32_t groupId = groupId_;
263 std::vector<sptr<VolumeGroupInfo>> volumeGroupInfos = {};
264 volumeGroupInfos = AudioPolicyManager::GetInstance().GetVolumeGroupInfos();
265 auto filter = [&groupId](const sptr<VolumeGroupInfo>& info) {
266 return groupId != info->volumeGroupId_;
267 };
268 volumeGroupInfos.erase(std::remove_if(volumeGroupInfos.begin(), volumeGroupInfos.end(), filter),
269 volumeGroupInfos.end());
270 if (volumeGroupInfos.size() > 0) {
271 netWorkId_ = volumeGroupInfos[0]->networkId_;
272 connectType_ = netWorkId_ == LOCAL_NETWORK_ID ? CONNECT_TYPE_LOCAL : CONNECT_TYPE_DISTRIBUTED;
273 AUDIO_INFO_LOG("AudioGroupManager::init set networkId %{public}s.", netWorkId_.c_str());
274 } else {
275 AUDIO_ERR_LOG("AudioGroupManager::init failed, has no valid group");
276 return ERROR;
277 }
278
279 // init g_sProxy
280 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
281 if (samgr == nullptr) {
282 AUDIO_ERR_LOG("AudioSystemManager::init failed");
283 return ERROR;
284 }
285
286 sptr<IRemoteObject> object = samgr->GetSystemAbility(AUDIO_DISTRIBUTED_SERVICE_ID);
287 if (object == nullptr) {
288 AUDIO_DEBUG_LOG("AudioSystemManager::object is NULL.");
289 return ERROR;
290 }
291 g_sProxy = iface_cast<IStandardAudioService>(object);
292 if (g_sProxy == nullptr) {
293 AUDIO_DEBUG_LOG("AudioSystemManager::init g_sProxy is NULL.");
294 return ERROR;
295 } else {
296 AUDIO_DEBUG_LOG("AudioSystemManager::init g_sProxy is assigned.");
297 return SUCCESS;
298 }
299 }
300
IsAlived()301 bool AudioGroupManager::IsAlived()
302 {
303 if (g_sProxy == nullptr) {
304 Init();
305 }
306
307 return (g_sProxy != nullptr) ? true : false;
308 }
309
GetGroupId()310 int32_t AudioGroupManager::GetGroupId()
311 {
312 return groupId_;
313 }
314
SetRingerModeCallback(const int32_t clientId,const std::shared_ptr<AudioRingerModeCallback> & callback)315 int32_t AudioGroupManager::SetRingerModeCallback(const int32_t clientId,
316 const std::shared_ptr<AudioRingerModeCallback> &callback)
317 {
318 if (callback == nullptr) {
319 AUDIO_ERR_LOG("AudioSystemManager: callback is nullptr");
320 return ERR_INVALID_PARAM;
321 }
322
323 cbClientId_ = clientId;
324
325 return AudioPolicyManager::GetInstance().SetRingerModeCallback(clientId, callback);
326 }
327
UnsetRingerModeCallback(const int32_t clientId) const328 int32_t AudioGroupManager::UnsetRingerModeCallback(const int32_t clientId) const
329 {
330 return AudioPolicyManager::GetInstance().UnsetRingerModeCallback(clientId);
331 }
332
SetRingerMode(AudioRingerMode ringMode) const333 int32_t AudioGroupManager::SetRingerMode(AudioRingerMode ringMode) const
334 {
335 if (netWorkId_ != LOCAL_NETWORK_ID) {
336 AUDIO_ERR_LOG("AudioGroupManager::SetRingerMode is not supported for local device.");
337 return ERROR;
338 }
339 /* Call Audio Policy SetRingerMode */
340 return AudioPolicyManager::GetInstance().SetRingerMode(ringMode);
341 }
342
GetRingerMode() const343 AudioRingerMode AudioGroupManager::GetRingerMode() const
344 {
345 /* Call Audio Policy GetRingerMode */
346 if (netWorkId_ != LOCAL_NETWORK_ID) {
347 AUDIO_ERR_LOG("AudioGroupManager::SetRingerMode is not supported for local device.");
348 return AudioRingerMode::RINGER_MODE_NORMAL;
349 }
350 return (AudioPolicyManager::GetInstance().GetRingerMode());
351 }
352
SetMicrophoneMute(bool isMute)353 int32_t AudioGroupManager::SetMicrophoneMute(bool isMute)
354 {
355 /* Call Audio Policy GetRingerMode */
356 if (netWorkId_ != LOCAL_NETWORK_ID) {
357 AUDIO_ERR_LOG("AudioGroupManager::SetRingerMode is not supported for local device.");
358 return ERROR;
359 }
360 return AudioPolicyManager::GetInstance().SetMicrophoneMuteAudioConfig(isMute);
361 }
362
IsMicrophoneMute(API_VERSION api_v)363 bool AudioGroupManager::IsMicrophoneMute(API_VERSION api_v)
364 {
365 /* Call Audio Policy GetRingerMode */
366 if (netWorkId_ != LOCAL_NETWORK_ID) {
367 AUDIO_ERR_LOG("AudioGroupManager::SetRingerMode is not supported for local device.");
368 return false;
369 }
370 return AudioPolicyManager::GetInstance().IsMicrophoneMute(api_v);
371 }
372
SetMicStateChangeCallback(const std::shared_ptr<AudioManagerMicStateChangeCallback> & callback)373 int32_t AudioGroupManager::SetMicStateChangeCallback(
374 const std::shared_ptr<AudioManagerMicStateChangeCallback> &callback)
375 {
376 AUDIO_INFO_LOG("Entered AudioRoutingManager::%{public}s", __func__);
377 if (callback == nullptr) {
378 AUDIO_ERR_LOG("setMicrophoneMuteCallback::callback is null");
379 return ERR_INVALID_PARAM;
380 }
381 int32_t clientId = static_cast<int32_t>(getpid());
382 return AudioPolicyManager::GetInstance().SetMicStateChangeCallback(clientId, callback);
383 }
384 } // namespace AudioStandard
385 } // namespace OHOS
386