• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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