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 #undef LOG_TAG
16 #define LOG_TAG "AudioZoneService"
17
18 #include "audio_zone_service.h"
19 #include "audio_log.h"
20 #include "audio_info.h"
21 #include "audio_errors.h"
22 #include "audio_zone.h"
23 #include "audio_zone_client_manager.h"
24 #include "audio_zone_interrupt_reporter.h"
25 #include "audio_device_lock.h"
26 #include "audio_connected_device.h"
27 #include "audio_core_service.h"
28 #include "audio_device_manager.h"
29 #include "audio_connected_device.h"
30
31 namespace OHOS {
32 namespace AudioStandard {
GetInstance()33 AudioZoneService& AudioZoneService::GetInstance()
34 {
35 static AudioZoneService service;
36 return service;
37 }
38
Init(std::shared_ptr<AudioPolicyServerHandler> handler,std::shared_ptr<AudioInterruptService> interruptService)39 void AudioZoneService::Init(std::shared_ptr<AudioPolicyServerHandler> handler,
40 std::shared_ptr<AudioInterruptService> interruptService)
41 {
42 CHECK_AND_RETURN_LOG(handler != nullptr && interruptService != nullptr,
43 "handler or interruptService is nullptr");
44 interruptService_ = interruptService;
45 zoneClientManager_ = std::make_shared<AudioZoneClientManager>(handler);
46 CHECK_AND_RETURN_LOG(zoneClientManager_ != nullptr, "create audio zone client manager failed");
47 handler->SetAudioZoneEventDispatcher(zoneClientManager_);
48 }
49
DeInit()50 void AudioZoneService::DeInit()
51 {
52 std::lock_guard<std::mutex> lock(zoneMutex_);
53 zoneMaps_.clear();
54 zoneReportClientList_.clear();
55 AudioZoneInterruptReporter::DisableAllInterruptReport();
56 zoneClientManager_ = nullptr;
57 interruptService_ = nullptr;
58 }
59
CreateAudioZone(const std::string & name,const AudioZoneContext & context,pid_t clientPid)60 int32_t AudioZoneService::CreateAudioZone(const std::string &name, const AudioZoneContext &context, pid_t clientPid)
61 {
62 std::shared_ptr<AudioZone> zone = std::make_shared<AudioZone>(zoneClientManager_, name, context, clientPid);
63 CHECK_AND_RETURN_RET_LOG(zone != nullptr, ERROR, "zone is nullptr");
64 int32_t zoneId = zone->GetId();
65 {
66 std::lock_guard<std::mutex> lock(zoneMutex_);
67 CHECK_AND_RETURN_RET_LOG(zoneMaps_.find(zoneId) == zoneMaps_.end(),
68 ERROR, "zone id %{public}d is duplicate", zoneId);
69
70 zoneMaps_[zoneId] = zone;
71
72 CHECK_AND_RETURN_RET_LOG(zoneClientManager_ != nullptr, ERROR, "zoneClientManager_ is nullptr");
73 for (auto &pid : zoneReportClientList_) {
74 zoneClientManager_->SendZoneAddEvent(pid, zone->GetDescriptor());
75 }
76
77 CHECK_AND_RETURN_RET_LOG(interruptService_ != nullptr, ERROR, "interruptService_ is nullptr");
78 interruptService_->CreateAudioInterruptZone(zoneId, context.focusStrategy_);
79 }
80 AUDIO_INFO_LOG("create zone id %{public}d, name %{public}s", zoneId, name.c_str());
81 return zoneId;
82 }
83
ReleaseAudioZone(int32_t zoneId)84 void AudioZoneService::ReleaseAudioZone(int32_t zoneId)
85 {
86 if (interruptService_ != nullptr) {
87 std::vector<int32_t> sessionUidList = interruptService_->GetAudioSessionUidList(zoneId);
88 for (auto uid : sessionUidList) {
89 RemoveUidFromAudioZone(zoneId, uid);
90 }
91 }
92
93 std::shared_ptr<AudioInterruptService> tmp = nullptr;
94 {
95 std::lock_guard<std::mutex> lock(zoneMutex_);
96 CHECK_AND_RETURN_LOG(zoneMaps_.find(zoneId) != zoneMaps_.end(),
97 "zone id %{public}d is not found", zoneId);
98
99 zoneMaps_.erase(zoneId);
100 tmp = interruptService_;
101 }
102
103 CHECK_AND_RETURN_LOG(tmp != nullptr, "interruptService tmp is nullptr");
104
105 auto reporters = AudioZoneInterruptReporter::CreateReporter(tmp,
106 zoneClientManager_, AudioZoneInterruptReason::RELEASE_AUDIO_ZONE);
107 tmp->ReleaseAudioInterruptZone(zoneId,
108 [this](int32_t uid, const std::string &deviceTag, const std::string &streamTag,
109 const StreamUsage &usage)->int32_t {
110 return this->FindAudioZoneByKey(uid, deviceTag, streamTag, usage);
111 });
112 for (auto &report : reporters) {
113 report->ReportInterrupt();
114 }
115
116 {
117 std::lock_guard<std::mutex> lock(zoneMutex_);
118 CHECK_AND_RETURN_LOG(zoneClientManager_ != nullptr, "zoneClientManager_ is nullptr");
119 for (auto &pid : zoneReportClientList_) {
120 zoneClientManager_->SendZoneRemoveEvent(pid, zoneId);
121 }
122 AUDIO_INFO_LOG("release zone id %{public}d", zoneId);
123 }
124 }
125
GetAllAudioZone()126 const std::vector<std::shared_ptr<AudioZoneDescriptor>> AudioZoneService::GetAllAudioZone()
127 {
128 std::vector<std::shared_ptr<AudioZoneDescriptor>> zoneDescriptor;
129 std::lock_guard<std::mutex> lock(zoneMutex_);
130 for (const auto &it : zoneMaps_) {
131 CHECK_AND_CONTINUE_LOG(it.second != nullptr, "zone is nullptr");
132 zoneDescriptor.emplace_back(it.second->GetDescriptor());
133 }
134 return zoneDescriptor;
135 }
136
GetAudioZone(int32_t zoneId)137 const std::shared_ptr<AudioZoneDescriptor> AudioZoneService::GetAudioZone(int32_t zoneId)
138 {
139 std::lock_guard<std::mutex> lock(zoneMutex_);
140 auto zone = FindZone(zoneId);
141 CHECK_AND_RETURN_RET_LOG(zone != nullptr, nullptr, "zone id %{public}d is not found", zoneId);
142 return zone->GetDescriptor();
143 }
144
GetAudioZoneByName(std::string name)145 int32_t AudioZoneService::GetAudioZoneByName(std::string name)
146 {
147 std::lock_guard<std::mutex> lock(zoneMutex_);
148 for (const auto &it : zoneMaps_) {
149 CHECK_AND_CONTINUE_LOG(it.second != nullptr, "zone is nullptr");
150 CHECK_AND_CONTINUE(it.second->GetName() == name);
151 AUDIO_INFO_LOG("find zone %{public}d by name: %{public}s", it.first, name.c_str());
152 return it.first;
153 }
154 return ERROR;
155 }
156
BindDeviceToAudioZone(int32_t zoneId,std::vector<std::shared_ptr<AudioDeviceDescriptor>> devices)157 int32_t AudioZoneService::BindDeviceToAudioZone(int32_t zoneId,
158 std::vector<std::shared_ptr<AudioDeviceDescriptor>> devices)
159 {
160 {
161 std::lock_guard<std::mutex> lock(zoneMutex_);
162 auto zone = FindZone(zoneId);
163 CHECK_AND_RETURN_RET_LOG(zone != nullptr, ERROR, "zone id %{public}d is not found", zoneId);
164
165 int ret = zone->AddDeviceDescriptor(devices);
166 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "bind device to zone failed");
167 }
168
169 for (auto device : devices) {
170 RemoveDeviceFromGlobal(device);
171 }
172 return SUCCESS;
173 }
174
RemoveDeviceFromGlobal(std::shared_ptr<AudioDeviceDescriptor> device)175 void AudioZoneService::RemoveDeviceFromGlobal(std::shared_ptr<AudioDeviceDescriptor> device)
176 {
177 CHECK_AND_RETURN_LOG(device != nullptr, "device is nullptr");
178 std::vector<std::shared_ptr<AudioDeviceDescriptor>> connectDevices;
179 AudioConnectedDevice::GetInstance().GetAllConnectedDeviceByType(device->networkId_,
180 device->deviceType_, device->macAddress_, device->deviceRole_, connectDevices);
181 CHECK_AND_RETURN_LOG(connectDevices.size() != 0, "connectDevices is empty.");
182 AudioDeviceStatus::GetInstance().RemoveDeviceFromGlobalOnly(device);
183 }
184
UnBindDeviceToAudioZone(int32_t zoneId,std::vector<std::shared_ptr<AudioDeviceDescriptor>> devices)185 int32_t AudioZoneService::UnBindDeviceToAudioZone(int32_t zoneId,
186 std::vector<std::shared_ptr<AudioDeviceDescriptor>> devices)
187 {
188 std::vector<std::shared_ptr<AudioDeviceDescriptor>> toGlobalDevices;
189 {
190 std::lock_guard<std::mutex> lock(zoneMutex_);
191 auto zone = FindZone(zoneId);
192 CHECK_AND_RETURN_RET_LOG(zone != nullptr, ERROR, "zone id %{public}d is not found", zoneId);
193
194 for (auto it : devices) {
195 CHECK_AND_CONTINUE(zone->IsDeviceConnect(it));
196 toGlobalDevices.push_back(it);
197 }
198 zone->RemoveDeviceDescriptor(devices);
199 }
200 // maybe whether or not add unbind devices to global is specified by caller
201 for (auto it : toGlobalDevices) {
202 AudioDeviceStatus::GetInstance().AddDeviceBackToGlobalOnly(it);
203 }
204 return SUCCESS;
205 }
206
MoveDeviceToGlobalFromZones(std::shared_ptr<AudioDeviceDescriptor> device)207 void AudioZoneService::MoveDeviceToGlobalFromZones(std::shared_ptr<AudioDeviceDescriptor> device)
208 {
209 bool findDeviceInZone = false;
210 {
211 std::lock_guard<std::mutex> lock(zoneMutex_);
212 for (auto &zoneMap : zoneMaps_) {
213 CHECK_AND_CONTINUE_LOG(zoneMap.second != nullptr, "zone is nullptr");
214 CHECK_AND_CONTINUE(zoneMap.second->IsDeviceConnect(device));
215
216 vector<std::shared_ptr<AudioDeviceDescriptor>> devices = {device};
217 zoneMap.second->RemoveDeviceDescriptor(devices);
218 findDeviceInZone = true;
219 }
220 }
221 CHECK_AND_RETURN(findDeviceInZone);
222 AudioDeviceManager::GetAudioDeviceManager().AddNewDevice(device);
223 AudioConnectedDevice::GetInstance().AddConnectedDevice(device);
224 }
225
RegisterAudioZoneClient(pid_t clientPid,sptr<IStandardAudioZoneClient> client)226 int32_t AudioZoneService::RegisterAudioZoneClient(pid_t clientPid, sptr<IStandardAudioZoneClient> client)
227 {
228 std::lock_guard<std::mutex> lock(zoneMutex_);
229 CHECK_AND_RETURN_RET_LOG(client != nullptr && zoneClientManager_ != nullptr, ERROR,
230 "client or zoneClientManager is nullptr");
231 zoneClientManager_->RegisterAudioZoneClient(clientPid, client);
232 return SUCCESS;
233 }
234
UnRegisterAudioZoneClient(pid_t clientPid)235 void AudioZoneService::UnRegisterAudioZoneClient(pid_t clientPid)
236 {
237 std::lock_guard<std::mutex> lock(zoneMutex_);
238 zoneReportClientList_.erase(clientPid);
239 AudioZoneInterruptReporter::DisableInterruptReport(clientPid);
240 for (const auto &it : zoneMaps_) {
241 it.second->EnableChangeReport(clientPid, false);
242 }
243 CHECK_AND_RETURN_LOG(zoneClientManager_ != nullptr, "zoneClientManager is nullptr");
244 zoneClientManager_->UnRegisterAudioZoneClient(clientPid);
245 }
246
EnableAudioZoneReport(pid_t clientPid,bool enable)247 int32_t AudioZoneService::EnableAudioZoneReport(pid_t clientPid, bool enable)
248 {
249 std::lock_guard<std::mutex> lock(zoneMutex_);
250 CHECK_AND_RETURN_RET_LOG(zoneClientManager_ != nullptr, ERROR, "zoneClientManager is nullptr");
251 if (enable) {
252 zoneReportClientList_.insert(clientPid);
253 } else {
254 zoneReportClientList_.erase(clientPid);
255 }
256 AUDIO_INFO_LOG("%{public}s zone event report to client %{public}d",
257 enable ? "enable" : "disable", clientPid);
258 return SUCCESS;
259 }
260
EnableAudioZoneChangeReport(pid_t clientPid,int32_t zoneId,bool enable)261 int32_t AudioZoneService::EnableAudioZoneChangeReport(pid_t clientPid,
262 int32_t zoneId, bool enable)
263 {
264 std::lock_guard<std::mutex> lock(zoneMutex_);
265 auto zone = FindZone(zoneId);
266 CHECK_AND_RETURN_RET_LOG(zone != nullptr, ERROR, "zone id %{public}d is not found", zoneId);
267
268 return zone->EnableChangeReport(clientPid, enable);
269 }
270
AddStreamToAudioZone(int32_t zoneId,AudioZoneStream stream)271 int32_t AudioZoneService::AddStreamToAudioZone(int32_t zoneId, AudioZoneStream stream)
272 {
273 return AddKeyToAudioZone(zoneId, INVALID_UID, "", "", stream.streamUsage);
274 }
275
AddStreamsToAudioZone(int32_t zoneId,std::vector<AudioZoneStream> streams)276 int32_t AudioZoneService::AddStreamsToAudioZone(int32_t zoneId, std::vector<AudioZoneStream> streams)
277 {
278 for (auto stream : streams) {
279 AddStreamToAudioZone(zoneId, stream);
280 }
281 return SUCCESS;
282 }
283
RemoveStreamFromAudioZone(int32_t zoneId,AudioZoneStream stream)284 int32_t AudioZoneService::RemoveStreamFromAudioZone(int32_t zoneId, AudioZoneStream stream)
285 {
286 return RemoveKeyFromAudioZone(zoneId, INVALID_UID, "", "", stream.streamUsage);
287 }
288
RemoveStreamsFromAudioZone(int32_t zoneId,std::vector<AudioZoneStream> streams)289 int32_t AudioZoneService::RemoveStreamsFromAudioZone(int32_t zoneId, std::vector<AudioZoneStream> streams)
290 {
291 std::shared_ptr<AudioInterruptService> tmp = nullptr;
292 {
293 std::lock_guard<std::mutex> lock(zoneMutex_);
294 auto zone = FindZone(zoneId);
295 CHECK_AND_RETURN_RET_LOG(zone != nullptr, ERROR, "zone id %{public}d is not found", zoneId);
296 for (auto stream : streams) {
297 zone->RemoveKey(AudioZoneBindKey(INVALID_UID, "", "", stream.streamUsage));
298 }
299 tmp = interruptService_;
300 }
301
302 CHECK_AND_RETURN_RET_LOG(tmp != nullptr, ERROR, "interruptService_ tmp is nullptr");
303
304 auto reporter = AudioZoneInterruptReporter::CreateReporter(tmp,
305 zoneClientManager_, AudioZoneInterruptReason::UNBIND_APP_FROM_ZONE);
306 tmp->MigrateAudioInterruptZone(zoneId,
307 [this](int32_t uid, const std::string &deviceTag, const std::string &streamTag,
308 const StreamUsage &usage)->int32_t {
309 return this->FindAudioZoneByKey(uid, deviceTag, streamTag, usage);
310 });
311 for (auto &report : reporter) {
312 report->ReportInterrupt();
313 }
314 return SUCCESS;
315 }
316
AddUidToAudioZone(int32_t zoneId,int32_t uid)317 int32_t AudioZoneService::AddUidToAudioZone(int32_t zoneId, int32_t uid)
318 {
319 return AddKeyToAudioZone(zoneId, uid, "", "", StreamUsage::STREAM_USAGE_INVALID);
320 }
321
SetZoneDeviceVisible(bool visible)322 void AudioZoneService::SetZoneDeviceVisible(bool visible)
323 {
324 std::lock_guard<std::mutex> lock(zoneMutex_);
325 zoneDeviceVisible_ = visible;
326 }
327
IsZoneDeviceVisible()328 bool AudioZoneService::IsZoneDeviceVisible()
329 {
330 std::lock_guard<std::mutex> lock(zoneMutex_);
331 return zoneDeviceVisible_;
332 }
333
AddKeyToAudioZone(int32_t zoneId,int32_t uid,const std::string & deviceTag,const std::string & streamTag,const StreamUsage & usage)334 int32_t AudioZoneService::AddKeyToAudioZone(int32_t zoneId, int32_t uid,
335 const std::string &deviceTag, const std::string &streamTag, const StreamUsage &usage)
336 {
337 std::shared_ptr<AudioInterruptService> tmp = nullptr;
338 int32_t srcZoneId;
339 {
340 AUDIO_DEBUG_LOG("add key %{public}d,%{public}s,%{public}s to zone %{public}d",
341 uid, deviceTag.c_str(), streamTag.c_str(), zoneId);
342 std::lock_guard<std::mutex> lock(zoneMutex_);
343 srcZoneId = FindAudioZoneByKey(uid, deviceTag, streamTag, usage);
344 auto zone = FindZone(zoneId);
345 CHECK_AND_RETURN_RET_LOG(zone != nullptr, ERROR, "zone id %{public}d is not found", zoneId);
346
347 for (const auto &it : zoneMaps_) {
348 CHECK_AND_CONTINUE_LOG(it.first != zoneId && it.second != nullptr,
349 "zoneId is duplicate or zone is nullptr");
350 it.second->RemoveKey(AudioZoneBindKey(uid, deviceTag, streamTag, usage));
351 }
352 zone->BindByKey(AudioZoneBindKey(uid, deviceTag, streamTag, usage));
353 tmp = interruptService_;
354 }
355
356 CHECK_AND_RETURN_RET_LOG(tmp != nullptr, ERROR, "interruptService_ tmp is nullptr");
357
358 auto reporter = AudioZoneInterruptReporter::CreateReporter(tmp,
359 zoneClientManager_, AudioZoneInterruptReason::BIND_APP_TO_ZONE);
360 tmp->MigrateAudioInterruptZone(srcZoneId,
361 [this](int32_t uid, const std::string &deviceTag, const std::string &streamTag,
362 const StreamUsage &usage)->int32_t {
363 return this->FindAudioZoneByKey(uid, deviceTag, streamTag, usage);
364 });
365 for (auto &report : reporter) {
366 report->ReportInterrupt();
367 }
368 return SUCCESS;
369 }
370
FindAudioZoneByUid(int32_t uid)371 int32_t AudioZoneService::FindAudioZoneByUid(int32_t uid)
372 {
373 std::lock_guard<std::mutex> lock(zoneMutex_);
374 return FindAudioZoneByKey(uid, "", "", StreamUsage::STREAM_USAGE_INVALID);
375 }
376
FindAudioSessionZoneid(int32_t callerUid,int32_t callerPid,bool isActivate)377 int32_t AudioZoneService::FindAudioSessionZoneid(int32_t callerUid, int32_t callerPid, bool isActivate)
378 {
379 int32_t zoneId;
380 std::shared_ptr<AudioInterruptService> tmp = nullptr;
381 {
382 std::lock_guard<std::mutex> lock(zoneMutex_);
383 zoneId = FindAudioZoneByKey(callerUid, "", "", StreamUsage::STREAM_USAGE_INVALID);
384 tmp = interruptService_;
385 }
386 CHECK_AND_RETURN_RET_LOG(tmp != nullptr, zoneId, "interruptService_ is nullptr");
387 StreamUsage streamUsage = tmp->GetAudioSessionStreamUsage(callerPid);
388 {
389 std::lock_guard<std::mutex> lock(zoneMutex_);
390 if (streamUsage == StreamUsage::STREAM_USAGE_INVALID) {
391 return zoneId;
392 }
393 zoneId = FindAudioZoneByKey(INVALID_UID, "", "", streamUsage);
394 AUDIO_INFO_LOG("get audio session zoneId:%{public}d streamUsage:%{public}d isActivate:%{public}d",
395 zoneId, streamUsage, isActivate);
396 }
397 isActivate ? AddUidToAudioZone(zoneId, callerUid) : RemoveUidFromAudioZone(zoneId, callerUid);
398 return zoneId;
399 }
400
FindAudioZone(int32_t uid,StreamUsage usage)401 int32_t AudioZoneService::FindAudioZone(int32_t uid, StreamUsage usage)
402 {
403 std::lock_guard<std::mutex> lock(zoneMutex_);
404 int32_t zoneId = FindAudioZoneByKey(uid, "", "", StreamUsage::STREAM_USAGE_INVALID);
405 return zoneId != 0 ? zoneId : FindAudioZoneByKey(INVALID_UID, "", "", usage);
406 }
407
FindAudioZoneByKey(int32_t uid,const std::string & deviceTag,const std::string & streamTag,const StreamUsage & usage)408 int32_t AudioZoneService::FindAudioZoneByKey(int32_t uid, const std::string &deviceTag,
409 const std::string &streamTag, const StreamUsage &usage)
410 {
411 auto keyList = AudioZoneBindKey::GetSupportKeys(uid, deviceTag, streamTag, usage);
412 for (const auto &key : keyList) {
413 for (const auto &it : zoneMaps_) {
414 CHECK_AND_CONTINUE(it.second != nullptr && it.second->IsContainKey(key));
415 return it.first;
416 }
417 }
418 return 0;
419 }
420
RemoveUidFromAudioZone(int32_t zoneId,int32_t uid)421 int32_t AudioZoneService::RemoveUidFromAudioZone(int32_t zoneId, int32_t uid)
422 {
423 return RemoveKeyFromAudioZone(zoneId, uid, "", "", StreamUsage::STREAM_USAGE_INVALID);
424 }
425
RemoveKeyFromAudioZone(int32_t zoneId,int32_t uid,const std::string & deviceTag,const std::string & streamTag,const StreamUsage & usage)426 int32_t AudioZoneService::RemoveKeyFromAudioZone(int32_t zoneId, int32_t uid,
427 const std::string &deviceTag, const std::string &streamTag, const StreamUsage &usage)
428 {
429 std::shared_ptr<AudioInterruptService> tmp = nullptr;
430 {
431 AUDIO_DEBUG_LOG("remove key %{public}d,%{public}s,%{public}s from zone %{public}d",
432 uid, deviceTag.c_str(), streamTag.c_str(), zoneId);
433 std::lock_guard<std::mutex> lock(zoneMutex_);
434 auto zone = FindZone(zoneId);
435 CHECK_AND_RETURN_RET_LOG(zone != nullptr, ERROR, "zone id %{public}d is not found", zoneId);
436
437 zone->RemoveKey(AudioZoneBindKey(uid, deviceTag, streamTag, usage));
438 tmp = interruptService_;
439 }
440
441 CHECK_AND_RETURN_RET_LOG(tmp != nullptr, ERROR, "interruptService_ tmp is nullptr");
442
443 auto reporter = AudioZoneInterruptReporter::CreateReporter(tmp,
444 zoneClientManager_, AudioZoneInterruptReason::UNBIND_APP_FROM_ZONE);
445 tmp->MigrateAudioInterruptZone(zoneId,
446 [this](int32_t uid, const std::string &deviceTag, const std::string &streamTag,
447 const StreamUsage &usage)->int32_t {
448 return this->FindAudioZoneByKey(uid, deviceTag, streamTag, usage);
449 });
450 for (auto &report : reporter) {
451 report->ReportInterrupt();
452 }
453 return SUCCESS;
454 }
455
EnableSystemVolumeProxy(pid_t clientPid,int32_t zoneId,bool enable)456 int32_t AudioZoneService::EnableSystemVolumeProxy(pid_t clientPid, int32_t zoneId, bool enable)
457 {
458 std::lock_guard<std::mutex> lock(zoneMutex_);
459 CHECK_AND_RETURN_RET_LOG(zoneClientManager_ != nullptr, ERROR, "zoneClientManager is nullptr");
460 CHECK_AND_RETURN_RET_LOG(zoneClientManager_->IsRegisterAudioZoneClient(clientPid), ERROR,
461 "client %{public}d for zone id %{public}d is not found", clientPid, zoneId);
462
463 auto zone = FindZone(zoneId);
464 CHECK_AND_RETURN_RET_LOG(zone != nullptr, ERROR, "zone id %{public}d is not found", zoneId);
465 return zone->EnableSystemVolumeProxy(clientPid, enable);
466 }
467
IsSystemVolumeProxyEnable(int32_t zoneId)468 bool AudioZoneService::IsSystemVolumeProxyEnable(int32_t zoneId)
469 {
470 std::lock_guard<std::mutex> lock(zoneMutex_);
471 auto zone = FindZone(zoneId);
472 CHECK_AND_RETURN_RET_LOG(zone != nullptr, ERROR, "zone id %{public}d is not found", zoneId);
473 return zone->IsVolumeProxyEnable();
474 }
475
SetSystemVolumeLevel(int32_t zoneId,AudioVolumeType volumeType,int32_t volumeLevel,int32_t volumeFlag)476 int32_t AudioZoneService::SetSystemVolumeLevel(int32_t zoneId, AudioVolumeType volumeType,
477 int32_t volumeLevel, int32_t volumeFlag)
478 {
479 std::lock_guard<std::mutex> lock(zoneMutex_);
480 auto zone = FindZone(zoneId);
481 CHECK_AND_RETURN_RET_LOG(zone != nullptr, ERROR, "zone id %{public}d is not found", zoneId);
482 CHECK_AND_RETURN_RET_LOG(zone->IsVolumeProxyEnable(), ERROR,
483 "zone id %{public}d IsVolumeProxyEnable is false", zoneId);
484 return zone->SetSystemVolumeLevel(volumeType, volumeLevel, volumeFlag);
485 }
486
GetSystemVolumeLevel(int32_t zoneId,AudioVolumeType volumeType)487 int32_t AudioZoneService::GetSystemVolumeLevel(int32_t zoneId, AudioVolumeType volumeType)
488 {
489 std::lock_guard<std::mutex> lock(zoneMutex_);
490 auto zone = FindZone(zoneId);
491 CHECK_AND_RETURN_RET_LOG(zone != nullptr, ERROR, "zone id %{public}d is not found", zoneId);
492 CHECK_AND_RETURN_RET_LOG(zone->IsVolumeProxyEnable(), ERROR,
493 "zone id %{public}d IsVolumeProxyEnable is false", zoneId);
494 return zone->GetSystemVolumeLevel(volumeType);
495 }
496
GetAudioInterruptForZone(int32_t zoneId)497 AudioZoneFocusList AudioZoneService::GetAudioInterruptForZone(int32_t zoneId)
498 {
499 std::lock_guard<std::mutex> lock(zoneMutex_);
500 AudioZoneFocusList interrupts;
501 CHECK_AND_RETURN_RET_LOG(CheckIsZoneValid(zoneId), interrupts, "zone id %{public}d is not valid", zoneId);
502 CHECK_AND_RETURN_RET_LOG(interruptService_ != nullptr, interrupts, "interruptService_ is nullptr");
503
504 interruptService_->GetAudioFocusInfoList(zoneId, interrupts);
505 return interrupts;
506 }
507
CheckIsZoneValid(int32_t zoneId)508 bool AudioZoneService::CheckIsZoneValid(int32_t zoneId)
509 {
510 if (zoneId < 0) {
511 return false;
512 }
513 if (zoneId == 0) {
514 return true;
515 }
516 return FindZone(zoneId) != nullptr;
517 }
518
CheckZoneExist(int32_t zoneId)519 bool AudioZoneService::CheckZoneExist(int32_t zoneId)
520 {
521 std::lock_guard<std::mutex> lock(zoneMutex_);
522 return CheckIsZoneValid(zoneId);
523 }
524
GetAudioInterruptForZone(int32_t zoneId,const std::string & deviceTag)525 AudioZoneFocusList AudioZoneService::GetAudioInterruptForZone(int32_t zoneId, const std::string &deviceTag)
526 {
527 std::lock_guard<std::mutex> lock(zoneMutex_);
528 AudioZoneFocusList interrupts;
529 CHECK_AND_RETURN_RET_LOG(CheckIsZoneValid(zoneId), interrupts, "zone id %{public}d is not valid", zoneId);
530 CHECK_AND_RETURN_RET_LOG(interruptService_ != nullptr, interrupts, "interruptService_ is nullptr");
531
532 interruptService_->GetAudioFocusInfoList(zoneId, deviceTag, interrupts);
533 return interrupts;
534 }
535
EnableAudioZoneInterruptReport(pid_t clientPid,int32_t zoneId,const std::string & deviceTag,bool enable)536 int32_t AudioZoneService::EnableAudioZoneInterruptReport(pid_t clientPid, int32_t zoneId,
537 const std::string &deviceTag, bool enable)
538 {
539 std::lock_guard<std::mutex> lock(zoneMutex_);
540 CHECK_AND_RETURN_RET_LOG(zoneClientManager_ != nullptr, ERROR,
541 "zoneClientManager is nullptr");
542 CHECK_AND_RETURN_RET_LOG(zoneClientManager_->IsRegisterAudioZoneClient(clientPid), ERROR,
543 "no register client %{public}d", clientPid);
544
545 return AudioZoneInterruptReporter::EnableInterruptReport(clientPid, zoneId, deviceTag, enable);
546 }
547
ActivateAudioInterrupt(int32_t zoneId,const AudioInterrupt & audioInterrupt,bool isUpdatedAudioStrategy)548 int32_t AudioZoneService::ActivateAudioInterrupt(int32_t zoneId,
549 const AudioInterrupt &audioInterrupt, bool isUpdatedAudioStrategy)
550 {
551 std::shared_ptr<AudioInterruptService> tmp = nullptr;
552 {
553 JUDGE_AND_INFO_LOG(zoneId != 0, "active interrupt of zone %{public}d", zoneId);
554 std::lock_guard<std::mutex> lock(zoneMutex_);
555 CHECK_AND_RETURN_RET_LOG(zoneClientManager_ != nullptr && interruptService_ != nullptr, ERROR,
556 "zoneClientManager or interruptService is nullptr");
557 CHECK_AND_RETURN_RET_LOG(CheckIsZoneValid(zoneId), ERROR,
558 "zone id %{public}d is not valid", zoneId);
559 tmp = interruptService_;
560 }
561
562 CHECK_AND_RETURN_RET_LOG(tmp != nullptr, ERROR, "interruptService_ tmp is nullptr");
563 auto reporters = AudioZoneInterruptReporter::CreateReporter(zoneId,
564 tmp, zoneClientManager_,
565 AudioZoneInterruptReason::REMOTE_INJECT);
566 int ret = tmp->ActivateAudioInterrupt(zoneId, audioInterrupt,
567 isUpdatedAudioStrategy);
568 for (auto &report : reporters) {
569 report->ReportInterrupt();
570 }
571 return ret;
572 }
573
DeactivateAudioInterrupt(int32_t zoneId,const AudioInterrupt & audioInterrupt)574 int32_t AudioZoneService::DeactivateAudioInterrupt(int32_t zoneId,
575 const AudioInterrupt &audioInterrupt)
576 {
577 std::shared_ptr<AudioInterruptService> tmp = nullptr;
578 {
579 JUDGE_AND_INFO_LOG(zoneId != 0, "deactive interrupt of zone %{public}d", zoneId);
580 std::lock_guard<std::mutex> lock(zoneMutex_);
581 CHECK_AND_RETURN_RET_LOG(zoneClientManager_ != nullptr && interruptService_ != nullptr, ERROR,
582 "zoneClientManager or interruptService is nullptr");
583 CHECK_AND_RETURN_RET_LOG(CheckIsZoneValid(zoneId), ERROR,
584 "zone id %{public}d is not valid", zoneId);
585 tmp = interruptService_;
586 }
587
588 CHECK_AND_RETURN_RET_LOG(tmp != nullptr, ERROR, "interruptService_ tmp is nullptr");
589 auto reporters = AudioZoneInterruptReporter::CreateReporter(zoneId,
590 tmp, zoneClientManager_,
591 AudioZoneInterruptReason::REMOTE_INJECT);
592 int ret = tmp->DeactivateAudioInterrupt(zoneId, audioInterrupt);
593 for (auto &report : reporters) {
594 report->ReportInterrupt();
595 }
596 return ret;
597 }
598
InjectInterruptToAudioZone(int32_t zoneId,const AudioZoneFocusList & interrupts)599 int32_t AudioZoneService::InjectInterruptToAudioZone(int32_t zoneId,
600 const AudioZoneFocusList &interrupts)
601 {
602 return InjectInterruptToAudioZone(zoneId, "", interrupts);
603 }
604
InjectInterruptToAudioZone(int32_t zoneId,const std::string & deviceTag,const AudioZoneFocusList & interrupts)605 int32_t AudioZoneService::InjectInterruptToAudioZone(int32_t zoneId, const std::string &deviceTag,
606 const AudioZoneFocusList &interrupts)
607 {
608 std::shared_ptr<AudioInterruptService> tmp = nullptr;
609 {
610 AUDIO_INFO_LOG("inject interrupt to zone %{public}d, device tag %{public}s",
611 zoneId, deviceTag.c_str());
612 std::lock_guard<std::mutex> lock(zoneMutex_);
613 CHECK_AND_RETURN_RET_LOG(zoneClientManager_ != nullptr && interruptService_ != nullptr, ERROR,
614 "zoneClientManager or interruptService is nullptr");
615 CHECK_AND_RETURN_RET_LOG(CheckIsZoneValid(zoneId), ERROR,
616 "zone id %{public}d is not valid", zoneId);
617 tmp = interruptService_;
618 }
619
620 CHECK_AND_RETURN_RET_LOG(tmp != nullptr, ERROR, "interruptService_ tmp is nullptr");
621 auto reporters = AudioZoneInterruptReporter::CreateReporter(zoneId,
622 tmp, zoneClientManager_,
623 AudioZoneInterruptReason::REMOTE_INJECT);
624 int32_t ret;
625 if (deviceTag.empty()) {
626 ret = tmp->InjectInterruptToAudioZone(zoneId, interrupts);
627 } else {
628 ret = tmp->InjectInterruptToAudioZone(zoneId, deviceTag, interrupts);
629 }
630 for (auto &report : reporters) {
631 report->ReportInterrupt();
632 }
633 return ret;
634 }
635
FetchOutputDevices(int32_t zoneId,StreamUsage streamUsage,int32_t clientUid,const RouterType & bypassType)636 std::vector<std::shared_ptr<AudioDeviceDescriptor>> AudioZoneService::FetchOutputDevices(int32_t zoneId,
637 StreamUsage streamUsage, int32_t clientUid, const RouterType &bypassType)
638 {
639 std::vector<std::shared_ptr<AudioDeviceDescriptor>> devices;
640 std::lock_guard<std::mutex> lock(zoneMutex_);
641 auto zone = FindZone(zoneId);
642 CHECK_AND_RETURN_RET_LOG(zone != nullptr, devices, "zone id %{public}d is not found", zoneId);
643
644 return zone->FetchOutputDevices(streamUsage, clientUid, bypassType);
645 }
646
FetchInputDevice(int32_t zoneId,SourceType sourceType,int32_t clientUid)647 std::shared_ptr<AudioDeviceDescriptor> AudioZoneService::FetchInputDevice(int32_t zoneId,
648 SourceType sourceType, int32_t clientUid)
649 {
650 std::lock_guard<std::mutex> lock(zoneMutex_);
651 auto zone = FindZone(zoneId);
652 CHECK_AND_RETURN_RET_LOG(zone != nullptr, nullptr, "zone id %{public}d is not found", zoneId);
653
654 return zone->FetchInputDevice(sourceType, clientUid);
655 }
656
FindZone(int32_t zoneId)657 std::shared_ptr<AudioZone> AudioZoneService::FindZone(int32_t zoneId)
658 {
659 auto it = zoneMaps_.find(zoneId);
660 CHECK_AND_RETURN_RET_LOG(it != zoneMaps_.end(), nullptr, "zone id %{public}d is not found", zoneId);
661
662 return zoneMaps_[zoneId];
663 }
664
GetZoneStringDescriptor(int32_t zoneId)665 const std::string AudioZoneService::GetZoneStringDescriptor(int32_t zoneId)
666 {
667 std::lock_guard<std::mutex> lock(zoneMutex_);
668 auto zone = FindZone(zoneId);
669 CHECK_AND_RETURN_RET_LOG(zone != nullptr, "", "zone id %{public}d is not found", zoneId);
670
671 return zone->GetStringDescriptor();
672 }
673
UpdateDeviceFromGlobalForAllZone(std::shared_ptr<AudioDeviceDescriptor> device)674 int32_t AudioZoneService::UpdateDeviceFromGlobalForAllZone(std::shared_ptr<AudioDeviceDescriptor> device)
675 {
676 std::lock_guard<std::mutex> lock(zoneMutex_);
677 CHECK_AND_RETURN_RET_LOG(device != nullptr, ERROR, "device is nullptr!");
678 for (const auto &it : zoneMaps_) {
679 CHECK_AND_CONTINUE_LOG(it.second != nullptr, "zone id %{public}d is nullptr", it.first);
680 int32_t res = it.second->UpdateDeviceDescriptor(device);
681 if (res == SUCCESS) {
682 AUDIO_INFO_LOG("zone id %{public}d enable device %{public}d success", it.first, device->deviceType_);
683 return res;
684 }
685 }
686 return ERROR;
687 }
688
ClearAudioFocusBySessionID(const int32_t & sessionID)689 int32_t AudioZoneService::ClearAudioFocusBySessionID(const int32_t &sessionID)
690 {
691 CHECK_AND_RETURN_RET_LOG(interruptService_ != nullptr, ERROR, "interruptService_ is nullptr");
692 return interruptService_->ClearAudioFocusBySessionID(sessionID);
693 }
694
ReleaseAudioZoneByClientPid(pid_t clientPid)695 void AudioZoneService::ReleaseAudioZoneByClientPid(pid_t clientPid)
696 {
697 int32_t zoneId;
698 {
699 std::lock_guard<std::mutex> lock(zoneMutex_);
700 auto findZone = [&clientPid] (const std::pair<int32_t, std::shared_ptr<AudioZone>> &item) {
701 CHECK_AND_RETURN_RET(item.second != nullptr, false);
702 return item.second->GetClientPid() == clientPid;
703 };
704
705 auto itZone = std::find_if(zoneMaps_.begin(), zoneMaps_.end(), findZone);
706 CHECK_AND_RETURN(itZone != zoneMaps_.end());
707 zoneId = itZone->first;
708 }
709
710 AUDIO_INFO_LOG("client %{public}d died, release zone %{public}d", clientPid, zoneId);
711 ReleaseAudioZone(zoneId);
712 }
713 } // namespace AudioStandard
714 } // namespace OHOS