• 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 #ifndef LOG_TAG
16 #define LOG_TAG "AudioZoneClient"
17 #endif
18 
19 #include "audio_zone_client.h"
20 #include "audio_errors.h"
21 #include "audio_utils.h"
22 #include "audio_policy_manager.h"
23 
24 namespace OHOS {
25 namespace AudioStandard {
26 static constexpr int32_t MAX_SIZE = 1024;
AudioZoneClient()27 AudioZoneClient::AudioZoneClient()
28 {}
29 
~AudioZoneClient()30 AudioZoneClient::~AudioZoneClient()
31 {}
32 
AddAudioZoneCallback(const std::shared_ptr<AudioZoneCallback> & callback)33 int32_t AudioZoneClient::AddAudioZoneCallback(const std::shared_ptr<AudioZoneCallback> &callback)
34 {
35     std::lock_guard<std::mutex> lk(audioZoneCallbackMutex_);
36     if (audioZoneCallback_ == nullptr) {
37         int32_t result = AudioPolicyManager::GetInstance().EnableAudioZoneReport(true);
38         CHECK_AND_RETURN_RET_LOG(result == SUCCESS, ERR_OPERATION_FAILED,
39             "EnableAudioZoneReport result:%{public}d", result);
40     }
41     audioZoneCallback_ = callback;
42     return SUCCESS;
43 }
44 
RemoveAudioZoneCallback()45 void AudioZoneClient::RemoveAudioZoneCallback()
46 {
47     std::lock_guard<std::mutex> lk(audioZoneCallbackMutex_);
48     CHECK_AND_RETURN_LOG(audioZoneCallback_ != nullptr, "audioZoneCallback is null.");
49     AudioPolicyManager::GetInstance().EnableAudioZoneReport(false);
50     audioZoneCallback_ = nullptr;
51 }
52 
AddAudioZoneChangeCallback(int32_t zoneId,const std::shared_ptr<AudioZoneChangeCallback> & callback)53 int32_t AudioZoneClient::AddAudioZoneChangeCallback(int32_t zoneId,
54     const std::shared_ptr<AudioZoneChangeCallback> &callback)
55 {
56     std::lock_guard<std::mutex> lk(audioZoneChangeMutex_);
57     if (audioZoneChangeCallbackMap_.find(zoneId) == audioZoneChangeCallbackMap_.end()) {
58         int32_t result = AudioPolicyManager::GetInstance().EnableAudioZoneChangeReport(zoneId, true);
59         CHECK_AND_RETURN_RET_LOG(result == SUCCESS, ERR_OPERATION_FAILED,
60             "EnableAudioZoneChangeReport result:%{public}d", result);
61     }
62     audioZoneChangeCallbackMap_[zoneId] = callback;
63     return SUCCESS;
64 }
65 
RemoveAudioZoneChangeCallback(int32_t zoneId)66 void AudioZoneClient::RemoveAudioZoneChangeCallback(int32_t zoneId)
67 {
68     std::lock_guard<std::mutex> lk(audioZoneChangeMutex_);
69     CHECK_AND_RETURN_LOG(audioZoneChangeCallbackMap_.find(zoneId) != audioZoneChangeCallbackMap_.end(),
70         "audioZoneChangeCallbackMap_ not find zoneId.");
71     AudioPolicyManager::GetInstance().EnableAudioZoneChangeReport(zoneId, false);
72     audioZoneChangeCallbackMap_.erase(zoneId);
73 }
74 
AddAudioZoneVolumeProxy(int32_t zoneId,const std::shared_ptr<AudioZoneVolumeProxy> & proxy)75 int32_t AudioZoneClient::AddAudioZoneVolumeProxy(int32_t zoneId,
76     const std::shared_ptr<AudioZoneVolumeProxy> &proxy)
77 {
78     std::lock_guard<std::mutex> lk(audioZoneVolumeProxyMutex_);
79     if (audioZoneVolumeProxyMap_.find(zoneId) == audioZoneVolumeProxyMap_.end()) {
80         int32_t result = AudioPolicyManager::GetInstance().EnableSystemVolumeProxy(zoneId, true);
81         CHECK_AND_RETURN_RET_LOG(result == SUCCESS, ERR_OPERATION_FAILED,
82             "EnableSystemVolumeProxy result:%{public}d", result);
83     }
84     audioZoneVolumeProxyMap_[zoneId] = proxy;
85     return SUCCESS;
86 }
87 
RemoveAudioZoneVolumeProxy(int32_t zoneId)88 void AudioZoneClient::RemoveAudioZoneVolumeProxy(int32_t zoneId)
89 {
90     std::lock_guard<std::mutex> lk(audioZoneVolumeProxyMutex_);
91     CHECK_AND_RETURN_LOG(audioZoneVolumeProxyMap_.find(zoneId) != audioZoneVolumeProxyMap_.end(),
92         "audioZoneVolumeProxyMap_ not find zoneId.");
93     AudioPolicyManager::GetInstance().EnableSystemVolumeProxy(zoneId, false);
94     audioZoneVolumeProxyMap_.erase(zoneId);
95 }
96 
AddAudioInterruptCallback(int32_t zoneId,const std::shared_ptr<AudioZoneInterruptCallback> & callback)97 int32_t AudioZoneClient::AddAudioInterruptCallback(int32_t zoneId,
98     const std::shared_ptr<AudioZoneInterruptCallback> &callback)
99 {
100     return AddAudioInterruptCallback(zoneId, "", callback);
101 }
102 
AddAudioInterruptCallback(int32_t zoneId,const std::string & deviceTag,const std::shared_ptr<AudioZoneInterruptCallback> & callback)103 int32_t AudioZoneClient::AddAudioInterruptCallback(int32_t zoneId, const std::string &deviceTag,
104     const std::shared_ptr<AudioZoneInterruptCallback> &callback)
105 {
106     std::string key = GetInterruptKeyId(zoneId, deviceTag);
107     std::lock_guard<std::mutex> lk(audioZoneInterruptMutex_);
108     if (audioZoneInterruptCallbackMap_.find(key) == audioZoneInterruptCallbackMap_.end()) {
109         int32_t result = AudioPolicyManager::GetInstance().EnableAudioZoneInterruptReport(zoneId, deviceTag, true);
110         CHECK_AND_RETURN_RET_LOG(result == SUCCESS, ERR_OPERATION_FAILED,
111             "EnableAudioZoneInterruptReport result:%{public}d", result);
112     }
113     audioZoneInterruptCallbackMap_[key] = callback;
114     return SUCCESS;
115 }
116 
RemoveAudioInterruptCallback(int32_t zoneId)117 void AudioZoneClient::RemoveAudioInterruptCallback(int32_t zoneId)
118 {
119     RemoveAudioInterruptCallback(zoneId, "");
120 }
121 
RemoveAudioInterruptCallback(int32_t zoneId,const std::string & deviceTag)122 void AudioZoneClient::RemoveAudioInterruptCallback(int32_t zoneId, const std::string &deviceTag)
123 {
124     std::string key = GetInterruptKeyId(zoneId, deviceTag);
125     std::lock_guard<std::mutex> lk(audioZoneInterruptMutex_);
126     CHECK_AND_RETURN_LOG(audioZoneInterruptCallbackMap_.find(key) != audioZoneInterruptCallbackMap_.end(),
127         "audioZoneInterruptCallbackMap_ not find key.");
128     AudioPolicyManager::GetInstance().EnableAudioZoneInterruptReport(zoneId, deviceTag, false);
129     audioZoneInterruptCallbackMap_.erase(key);
130 }
131 
Restore()132 void AudioZoneClient::Restore()
133 {
134     {
135         std::lock_guard<std::mutex> lk(audioZoneCallbackMutex_);
136         if (audioZoneCallback_ != nullptr) {
137             int32_t result = AudioPolicyManager::GetInstance().EnableAudioZoneReport(true);
138             AUDIO_INFO_LOG("EnableAudioZoneReport result:%{public}d", result);
139         }
140     }
141 
142     {
143         std::lock_guard<std::mutex> lk(audioZoneChangeMutex_);
144         for (const auto &it : audioZoneChangeCallbackMap_) {
145             int32_t result = AudioPolicyManager::GetInstance().EnableAudioZoneChangeReport(it.first, true);
146             AUDIO_INFO_LOG("EnableAudioZoneChangeReport result:%{public}d", result);
147         }
148     }
149 
150     {
151         std::lock_guard<std::mutex> lk(audioZoneVolumeProxyMutex_);
152         for (const auto &it : audioZoneVolumeProxyMap_) {
153             int32_t result = AudioPolicyManager::GetInstance().EnableSystemVolumeProxy(it.first, true);
154             AUDIO_INFO_LOG("EnableSystemVolumeProxy result:%{public}d", result);
155         }
156     }
157 
158     {
159         std::lock_guard<std::mutex> lk(audioZoneInterruptMutex_);
160         for (const auto &it : audioZoneInterruptCallbackMap_) {
161             std::size_t pos = it.first.find('&');
162             CHECK_AND_RETURN_LOG(pos != std::string::npos, "error str:%{public}s", it.first.c_str());
163             std::string zoneIdStr = it.first.substr(0, pos);
164             std::string deviceTag = it.first.substr(pos + 1);
165             int32_t zoneId = 0;
166             auto [ptr, ec] = std::from_chars(zoneIdStr.data(), zoneIdStr.data() + zoneIdStr.size(), zoneId);
167             (void)ptr;
168             CHECK_AND_CONTINUE_LOG(ec != std::errc::invalid_argument, "%{public}s is not a number", zoneIdStr.c_str());
169             CHECK_AND_CONTINUE_LOG(ec != std::errc::result_out_of_range,
170                 "%{public}s is out of range", zoneIdStr.c_str());
171             int32_t result = AudioPolicyManager::GetInstance().EnableAudioZoneInterruptReport(zoneId, deviceTag, true);
172             AUDIO_INFO_LOG("EnableAudioZoneInterruptReport result:%{public}d", result);
173         }
174     }
175 }
176 
GetInterruptKeyId(int32_t zoneId,const std::string & deviceTag)177 std::string AudioZoneClient::GetInterruptKeyId(int32_t zoneId, const std::string &deviceTag)
178 {
179     return std::to_string(zoneId) + "&" + deviceTag;
180 }
181 
OnAudioZoneAdd(const AudioZoneDescriptor & zoneDescriptor)182 int32_t AudioZoneClient::OnAudioZoneAdd(const AudioZoneDescriptor &zoneDescriptor)
183 {
184     std::lock_guard<std::mutex> lk(audioZoneCallbackMutex_);
185     CHECK_AND_RETURN_RET_LOG(audioZoneCallback_ != nullptr, ERR_OPERATION_FAILED, "audioZoneCallback_ is null.");
186     audioZoneCallback_->OnAudioZoneAdd(zoneDescriptor);
187     return SUCCESS;
188 }
189 
OnAudioZoneRemove(int32_t zoneId)190 int32_t AudioZoneClient::OnAudioZoneRemove(int32_t zoneId)
191 {
192     std::lock_guard<std::mutex> lk(audioZoneCallbackMutex_);
193     CHECK_AND_RETURN_RET_LOG(audioZoneCallback_ != nullptr, ERR_OPERATION_FAILED, "audioZoneCallback_ is null.");
194     audioZoneCallback_->OnAudioZoneRemove(zoneId);
195     return SUCCESS;
196 }
197 
OnAudioZoneChange(int32_t zoneId,const AudioZoneDescriptor & zoneDescriptor,int32_t reason)198 int32_t AudioZoneClient::OnAudioZoneChange(int32_t zoneId, const AudioZoneDescriptor &zoneDescriptor,
199     int32_t reason)
200 {
201     std::lock_guard<std::mutex> lk(audioZoneCallbackMutex_);
202     CHECK_AND_RETURN_RET_LOG(audioZoneChangeCallbackMap_.find(zoneId) != audioZoneChangeCallbackMap_.end(),
203         ERR_OPERATION_FAILED, "audioZoneChangeCallbackMap_ not find zoneId %{public}d.", zoneId);
204     CHECK_AND_RETURN_RET_LOG(audioZoneChangeCallbackMap_[zoneId] != nullptr,
205         ERR_OPERATION_FAILED, "audioZoneChangeCallback is nullptr, zoneId %{public}d.", zoneId);
206     audioZoneChangeCallbackMap_[zoneId]->OnAudioZoneChange(zoneDescriptor,
207         static_cast<AudioZoneChangeReason>(reason));
208     return SUCCESS;
209 }
210 
OnInterruptEvent(int32_t zoneId,const std::vector<std::map<AudioInterrupt,int32_t>> & ipcInterrupts,int32_t reason)211 int32_t AudioZoneClient::OnInterruptEvent(int32_t zoneId,
212     const std::vector<std::map<AudioInterrupt, int32_t>> &ipcInterrupts,
213     int32_t reason)
214 {
215     int32_t size = static_cast<int32_t>(ipcInterrupts.size());
216     CHECK_AND_RETURN_RET_LOG(size > 0 && size < MAX_SIZE, ERR_INVALID_PARAM,
217         "invalid interrupt size: %{public}d", size);
218     OnInterruptEvent(zoneId, "", ipcInterrupts, reason);
219     return SUCCESS;
220 }
221 
OnInterruptEvent(int32_t zoneId,const std::string & deviceTag,const std::vector<std::map<AudioInterrupt,int32_t>> & ipcInterrupts,int32_t reason)222 int32_t AudioZoneClient::OnInterruptEvent(int32_t zoneId, const std::string &deviceTag,
223     const std::vector<std::map<AudioInterrupt, int32_t>> &ipcInterrupts,
224     int32_t reason)
225 {
226     std::list<std::pair<AudioInterrupt, AudioFocuState>> interrupts;
227     for (const auto& map : ipcInterrupts) {
228         for (const auto& [key, value] : map) {
229             interrupts.emplace_back(key, static_cast<AudioFocuState>(value));
230         }
231     }
232 
233     std::string key = GetInterruptKeyId(zoneId, deviceTag);
234     std::lock_guard<std::mutex> lk(audioZoneInterruptMutex_);
235     CHECK_AND_RETURN_RET_LOG(audioZoneInterruptCallbackMap_.find(key) != audioZoneInterruptCallbackMap_.end(),
236         ERR_OPERATION_FAILED, "audioZoneInterruptCallbackMap_ not find key %{public}s.", key.c_str());
237     CHECK_AND_RETURN_RET_LOG(audioZoneInterruptCallbackMap_[key] != nullptr,
238         ERR_OPERATION_FAILED, "audioZoneInterruptCallback is nullptr, key %{public}s.", key.c_str());
239 
240     audioZoneInterruptCallbackMap_[key]->OnInterruptEvent(interrupts,
241         static_cast<AudioZoneInterruptReason>(reason));
242     return SUCCESS;
243 }
244 
SetSystemVolume(int32_t zoneId,int32_t volumeType,int32_t volumeLevel,int32_t volumeFlag)245 int32_t AudioZoneClient::SetSystemVolume(int32_t zoneId, int32_t volumeType,
246     int32_t volumeLevel, int32_t volumeFlag)
247 {
248     std::lock_guard<std::mutex> lk(audioZoneVolumeProxyMutex_);
249     CHECK_AND_RETURN_RET_LOG(audioZoneVolumeProxyMap_.find(zoneId) != audioZoneVolumeProxyMap_.end(),
250         ERR_OPERATION_FAILED, "audioZoneVolumeProxyMap_ not find zoneId %{public}d.", zoneId);
251     CHECK_AND_RETURN_RET_LOG(audioZoneVolumeProxyMap_[zoneId] != nullptr,
252         ERR_OPERATION_FAILED, "audioZoneVolumeProxy is nullptr, zoneId %{public}d.", zoneId);
253 
254     audioZoneVolumeProxyMap_[zoneId]->SetSystemVolume(static_cast<AudioVolumeType>(volumeType),
255         volumeLevel);
256     return SUCCESS;
257 }
258 
GetSystemVolume(int32_t zoneId,int32_t volumeType,float & outVolume)259 int32_t AudioZoneClient::GetSystemVolume(int32_t zoneId, int32_t volumeType, float &outVolume)
260 {
261     std::lock_guard<std::mutex> lk(audioZoneVolumeProxyMutex_);
262     CHECK_AND_RETURN_RET_LOG(audioZoneVolumeProxyMap_.find(zoneId) != audioZoneVolumeProxyMap_.end(),
263         ERR_OPERATION_FAILED, "audioZoneVolumeProxyMap_ not find zoneId %{public}d.", zoneId);
264     CHECK_AND_RETURN_RET_LOG(audioZoneVolumeProxyMap_[zoneId] != nullptr,
265         ERR_OPERATION_FAILED, "audioZoneVolumeProxy is nullptr, zoneId %{public}d.", zoneId);
266 
267     outVolume = audioZoneVolumeProxyMap_[zoneId]->GetSystemVolume(static_cast<AudioVolumeType>(volumeType));
268     return SUCCESS;
269 }
270 }  // namespace AudioStandard
271 }  // namespace OHOS
272 
273