1 /*
2 * Copyright (c) 2023 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 "AudioSpatializationService"
17 #endif
18
19 #include <openssl/sha.h>
20 #include "audio_spatialization_service.h"
21
22 #include "iservice_registry.h"
23 #include "system_ability_definition.h"
24
25 #include "audio_spatialization_state_change_listener_proxy.h"
26
27 #include "audio_policy_service.h"
28
29 namespace OHOS {
30 namespace AudioStandard {
31 using namespace std;
32
33 static const int32_t SPATIALIZATION_SERVICE_OK = 0;
34 static const std::string BLUETOOTH_EFFECT_CHAIN_NAME = "EFFECTCHAIN_BT_MUSIC";
35 static const std::string SPATIALIZATION_AND_HEAD_TRACKING_SUPPORTED_LABEL = "SPATIALIZATION_AND_HEADTRACKING";
36 static const std::string SPATIALIZATION_SUPPORTED_LABEL = "SPATIALIZATION";
37 static const std::string HEAD_TRACKING_SUPPORTED_LABEL = "HEADTRACKING";
38 static const std::string SPATIALIZATION_STATE_SETTINGKEY = "spatialization_state";
39 static const std::string SPATIALIZATION_SCENE_SETTINGKEY = "spatialization_scene";
40 static const std::string PRE_SETTING_SPATIAL_ADDRESS = "pre_setting_spatial_address";
41 static sptr<IStandardAudioService> g_adProxy = nullptr;
42 mutex g_adSpatializationProxyMutex;
43
44 enum SpatializationStateOffset {
45 SPATIALIZATION_OFFSET,
46 HEADTRACKING_OFFSET
47 };
48
UnpackSpatializationState(uint32_t pack,AudioSpatializationState & state)49 static void UnpackSpatializationState(uint32_t pack, AudioSpatializationState &state)
50 {
51 state = {.spatializationEnabled = pack >> SPATIALIZATION_OFFSET & 1,
52 .headTrackingEnabled = pack >> HEADTRACKING_OFFSET & 1};
53 }
54
PackSpatializationState(AudioSpatializationState state)55 static uint32_t PackSpatializationState(AudioSpatializationState state)
56 {
57 return (state.spatializationEnabled << SPATIALIZATION_OFFSET) |
58 (state.headTrackingEnabled << HEADTRACKING_OFFSET);
59 }
60
IsAudioSpatialDeviceStateEqual(const AudioSpatialDeviceState & a,const AudioSpatialDeviceState & b)61 static bool IsAudioSpatialDeviceStateEqual(const AudioSpatialDeviceState &a, const AudioSpatialDeviceState &b)
62 {
63 return ((a.isSpatializationSupported == b.isSpatializationSupported) &&
64 (a.isHeadTrackingSupported == b.isHeadTrackingSupported) && (a.spatialDeviceType == b.spatialDeviceType));
65 }
66
IsSpatializationSupportedUsage(StreamUsage usage)67 static bool IsSpatializationSupportedUsage(StreamUsage usage)
68 {
69 return usage != STREAM_USAGE_GAME;
70 }
71
~AudioSpatializationService()72 AudioSpatializationService::~AudioSpatializationService()
73 {
74 AUDIO_ERR_LOG("~AudioSpatializationService()");
75 }
76
Init(const std::vector<EffectChain> & effectChains)77 void AudioSpatializationService::Init(const std::vector<EffectChain> &effectChains)
78 {
79 for (auto effectChain: effectChains) {
80 if (effectChain.name != BLUETOOTH_EFFECT_CHAIN_NAME) {
81 continue;
82 }
83 if (effectChain.label == SPATIALIZATION_AND_HEAD_TRACKING_SUPPORTED_LABEL) {
84 isSpatializationSupported_ = true;
85 isHeadTrackingSupported_ = true;
86 } else if (effectChain.label == SPATIALIZATION_SUPPORTED_LABEL) {
87 isSpatializationSupported_ = true;
88 } else if (effectChain.label == HEAD_TRACKING_SUPPORTED_LABEL) {
89 isHeadTrackingSupported_ = true;
90 }
91 }
92 UpdateSpatializationStateReal(false);
93 }
94
Deinit(void)95 void AudioSpatializationService::Deinit(void)
96 {
97 return;
98 }
99
GetAudioServerProxy()100 const sptr<IStandardAudioService> AudioSpatializationService::GetAudioServerProxy()
101 {
102 AUDIO_DEBUG_LOG("[Spatialization Service] Start get audio spatialization service proxy.");
103 lock_guard<mutex> lock(g_adSpatializationProxyMutex);
104
105 if (g_adProxy == nullptr) {
106 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
107 CHECK_AND_RETURN_RET_LOG(samgr != nullptr, nullptr,
108 "[Spatialization Service] Get samgr failed.");
109
110 sptr<IRemoteObject> object = samgr->GetSystemAbility(AUDIO_DISTRIBUTED_SERVICE_ID);
111 CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr,
112 "[Spatialization Service] audio service remote object is NULL.");
113
114 g_adProxy = iface_cast<IStandardAudioService>(object);
115 CHECK_AND_RETURN_RET_LOG(g_adProxy != nullptr, nullptr,
116 "[Spatialization Service] init g_adProxy is NULL.");
117 }
118 const sptr<IStandardAudioService> gsp = g_adProxy;
119 return gsp;
120 }
121
IsSpatializationEnabled()122 bool AudioSpatializationService::IsSpatializationEnabled()
123 {
124 std::lock_guard<std::mutex> lock(spatializationServiceMutex_);
125 if (preSettingSpatialAddress_ != "NO_PREVIOUS_SET_DEVICE") {
126 return addressToSpatialEnabledMap_[preSettingSpatialAddress_].spatializationEnabled;
127 }
128 return spatializationStateFlag_.spatializationEnabled;
129 }
130
IsSpatializationEnabled(const std::string address)131 bool AudioSpatializationService::IsSpatializationEnabled(const std::string address)
132 {
133 std::lock_guard<std::mutex> lock(spatializationServiceMutex_);
134 std::string encryptedAddress = GetSha256EncryptAddress(address);
135 CHECK_AND_RETURN_RET_LOG(addressToSpatialEnabledMap_.count(encryptedAddress), false,
136 "specified address for set spatialization enabled is not in memory");
137 return addressToSpatialEnabledMap_[encryptedAddress].spatializationEnabled;
138 }
139
SetSpatializationEnabled(const bool enable)140 int32_t AudioSpatializationService::SetSpatializationEnabled(const bool enable)
141 {
142 AUDIO_INFO_LOG("Spatialization enabled is set to be: %{public}d", enable);
143 std::lock_guard<std::mutex> lock(spatializationServiceMutex_);
144 if (preSettingSpatialAddress_ != "NO_PREVIOUS_SET_DEVICE") {
145 addressToSpatialEnabledMap_[preSettingSpatialAddress_].spatializationEnabled = enable;
146 return SPATIALIZATION_SERVICE_OK;
147 }
148 if (spatializationStateFlag_.spatializationEnabled == enable) {
149 return SPATIALIZATION_SERVICE_OK;
150 }
151 spatializationStateFlag_.spatializationEnabled = enable;
152 HandleSpatializationEnabledChange(enable);
153 if (UpdateSpatializationStateReal(false) != 0) {
154 return ERROR;
155 }
156 WriteSpatializationStateToDb(WRITE_SPATIALIZATION_STATE);
157 return SPATIALIZATION_SERVICE_OK;
158 }
159
SetSpatializationEnabled(const sptr<AudioDeviceDescriptor> & selectedAudioDevice,const bool enable)160 int32_t AudioSpatializationService::SetSpatializationEnabled(const sptr<AudioDeviceDescriptor> &selectedAudioDevice,
161 const bool enable)
162 {
163 std::lock_guard<std::mutex> lock(spatializationServiceMutex_);
164 std::string address = selectedAudioDevice->macAddress_;
165 std::string encryptedAddress = GetSha256EncryptAddress(address);
166 AUDIO_INFO_LOG("Device SpatializationEnabled is set to be: %{public}d", enable);
167 preSettingSpatialAddress_ = encryptedAddress;
168 if (addressToSpatialEnabledMap_.find(encryptedAddress) != addressToSpatialEnabledMap_.end() &&
169 addressToSpatialEnabledMap_[encryptedAddress].spatializationEnabled == enable) {
170 return SPATIALIZATION_SERVICE_OK;
171 }
172 addressToSpatialEnabledMap_[encryptedAddress].spatializationEnabled = enable;
173 HandleSpatializationEnabledChange(selectedAudioDevice, enable);
174 std::string deviceSpatialInfo = EncapsulateDeviceInfo(address);
175 UpdateDeviceSpatialMapInfo(address, deviceSpatialInfo);
176 if (UpdateSpatializationStateReal(false) != 0) {
177 return ERROR;
178 }
179 WriteSpatializationStateToDb(WRITE_DEVICESPATIAL_INFO, address);
180 return SPATIALIZATION_SERVICE_OK;
181 }
182
IsHeadTrackingEnabled()183 bool AudioSpatializationService::IsHeadTrackingEnabled()
184 {
185 std::lock_guard<std::mutex> lock(spatializationServiceMutex_);
186 if (preSettingSpatialAddress_ != "NO_PREVIOUS_SET_DEVICE") {
187 return addressToSpatialEnabledMap_[preSettingSpatialAddress_].headTrackingEnabled;
188 }
189 return spatializationStateFlag_.headTrackingEnabled;
190 }
191
IsHeadTrackingEnabled(const std::string address)192 bool AudioSpatializationService::IsHeadTrackingEnabled(const std::string address)
193 {
194 std::lock_guard<std::mutex> lock(spatializationServiceMutex_);
195 std::string encryptedAddress = GetSha256EncryptAddress(address);
196 CHECK_AND_RETURN_RET_LOG(addressToSpatialEnabledMap_.count(encryptedAddress), false,
197 "specified address for set head tracking enabled is not in memory");
198 return addressToSpatialEnabledMap_[encryptedAddress].headTrackingEnabled;
199 }
200
SetHeadTrackingEnabled(const bool enable)201 int32_t AudioSpatializationService::SetHeadTrackingEnabled(const bool enable)
202 {
203 AUDIO_INFO_LOG("Head tracking enabled is set to be: %{public}d", enable);
204 std::lock_guard<std::mutex> lock(spatializationServiceMutex_);
205 if (preSettingSpatialAddress_ != "NO_PREVIOUS_SET_DEVICE") {
206 addressToSpatialEnabledMap_[preSettingSpatialAddress_].headTrackingEnabled = enable;
207 return SPATIALIZATION_SERVICE_OK;
208 }
209 if (spatializationStateFlag_.headTrackingEnabled == enable) {
210 return SPATIALIZATION_SERVICE_OK;
211 }
212 spatializationStateFlag_.headTrackingEnabled = enable;
213 HandleHeadTrackingEnabledChange(enable);
214 if (UpdateSpatializationStateReal(false) != 0) {
215 return ERROR;
216 }
217 WriteSpatializationStateToDb(WRITE_SPATIALIZATION_STATE);
218 return SPATIALIZATION_SERVICE_OK;
219 }
220
SetHeadTrackingEnabled(const sptr<AudioDeviceDescriptor> & selectedAudioDevice,const bool enable)221 int32_t AudioSpatializationService::SetHeadTrackingEnabled(const sptr<AudioDeviceDescriptor> &selectedAudioDevice,
222 const bool enable)
223 {
224 std::lock_guard<std::mutex> lock(spatializationServiceMutex_);
225 std::string address = selectedAudioDevice->macAddress_;
226 std::string encryptedAddress = GetSha256EncryptAddress(address);
227 AUDIO_INFO_LOG("Device HeadTrackingEnabled is set to be: %{public}d", enable);
228 preSettingSpatialAddress_ = encryptedAddress;
229 if (addressToSpatialEnabledMap_.find(encryptedAddress) != addressToSpatialEnabledMap_.end() &&
230 addressToSpatialEnabledMap_[encryptedAddress].headTrackingEnabled == enable) {
231 return SPATIALIZATION_SERVICE_OK;
232 }
233 addressToSpatialEnabledMap_[encryptedAddress].headTrackingEnabled = enable;
234 HandleHeadTrackingEnabledChange(selectedAudioDevice, enable);
235 std::string deviceSpatialInfo = EncapsulateDeviceInfo(address);
236 UpdateDeviceSpatialMapInfo(address, deviceSpatialInfo);
237 if (UpdateSpatializationStateReal(false) != 0) {
238 return ERROR;
239 }
240 WriteSpatializationStateToDb(WRITE_DEVICESPATIAL_INFO, address);
241 return SPATIALIZATION_SERVICE_OK;
242 }
243
HandleSpatializationEnabledChange(const bool & enabled)244 void AudioSpatializationService::HandleSpatializationEnabledChange(const bool &enabled)
245 {
246 AUDIO_INFO_LOG("Spatialization enabled callback is triggered: state is %{public}d", enabled);
247 if (audioPolicyServerHandler_ != nullptr) {
248 audioPolicyServerHandler_->SendSpatializatonEnabledChangeEvent(enabled);
249 }
250 }
251
HandleSpatializationEnabledChange(const sptr<AudioDeviceDescriptor> & selectedAudioDevice,const bool & enabled)252 void AudioSpatializationService::HandleSpatializationEnabledChange(const sptr<AudioDeviceDescriptor>
253 &selectedAudioDevice, const bool &enabled)
254 {
255 AUDIO_INFO_LOG("device Spatialization enabled callback is triggered: state is %{public}d", enabled);
256 if (audioPolicyServerHandler_ != nullptr) {
257 audioPolicyServerHandler_->SendSpatializatonEnabledChangeForAnyDeviceEvent(selectedAudioDevice, enabled);
258 }
259 }
260
HandleHeadTrackingEnabledChange(const bool & enabled)261 void AudioSpatializationService::HandleHeadTrackingEnabledChange(const bool &enabled)
262 {
263 AUDIO_INFO_LOG("Head tracking enabled callback is triggered: state is %{public}d", enabled);
264 if (audioPolicyServerHandler_ != nullptr) {
265 audioPolicyServerHandler_->SendHeadTrackingEnabledChangeEvent(enabled);
266 }
267 }
268
HandleHeadTrackingEnabledChange(const sptr<AudioDeviceDescriptor> & selectedAudioDevice,const bool & enabled)269 void AudioSpatializationService::HandleHeadTrackingEnabledChange(const sptr<AudioDeviceDescriptor> &selectedAudioDevice,
270 const bool &enabled)
271 {
272 AUDIO_INFO_LOG("device Head tracking enabled callback is triggered: state is %{public}d", enabled);
273 if (audioPolicyServerHandler_ != nullptr) {
274 audioPolicyServerHandler_->SendHeadTrackingEnabledChangeForAnyDeviceEvent(selectedAudioDevice, enabled);
275 }
276 }
277
GetSpatializationState(const StreamUsage streamUsage)278 AudioSpatializationState AudioSpatializationService::GetSpatializationState(const StreamUsage streamUsage)
279 {
280 std::lock_guard<std::mutex> lock(spatializationServiceMutex_);
281 AudioSpatializationState spatializationState = {false, false};
282 if (IsSpatializationSupportedUsage(streamUsage)) {
283 spatializationState.spatializationEnabled = spatializationEnabledReal_;
284 spatializationState.headTrackingEnabled = headTrackingEnabledReal_;
285 }
286 return spatializationState;
287 }
288
IsSpatializationSupported()289 bool AudioSpatializationService::IsSpatializationSupported()
290 {
291 return isSpatializationSupported_;
292 }
293
IsSpatializationSupportedForDevice(const std::string address)294 bool AudioSpatializationService::IsSpatializationSupportedForDevice(const std::string address)
295 {
296 std::lock_guard<std::mutex> lock(spatializationSupportedMutex_);
297 std::string encryptedAddress = GetSha256EncryptAddress(address);
298 if (!addressToSpatialDeviceStateMap_.count(encryptedAddress)) {
299 AUDIO_INFO_LOG("specified address for spatialization is not in memory");
300 return false;
301 }
302 return addressToSpatialDeviceStateMap_[encryptedAddress].isSpatializationSupported;
303 }
304
IsHeadTrackingSupported()305 bool AudioSpatializationService::IsHeadTrackingSupported()
306 {
307 return isHeadTrackingSupported_;
308 }
309
IsHeadTrackingSupportedForDevice(const std::string address)310 bool AudioSpatializationService::IsHeadTrackingSupportedForDevice(const std::string address)
311 {
312 std::lock_guard<std::mutex> lock(spatializationSupportedMutex_);
313 std::string encryptedAddress = GetSha256EncryptAddress(address);
314 if (!addressToSpatialDeviceStateMap_.count(encryptedAddress)) {
315 AUDIO_INFO_LOG("specified address for head tracking is not in memory");
316 return false;
317 }
318 return addressToSpatialDeviceStateMap_[encryptedAddress].isHeadTrackingSupported;
319 }
320
UpdateSpatialDeviceState(const AudioSpatialDeviceState audioSpatialDeviceState)321 int32_t AudioSpatializationService::UpdateSpatialDeviceState(const AudioSpatialDeviceState audioSpatialDeviceState)
322 {
323 AUDIO_INFO_LOG("UpdateSpatialDeviceState Entered, "
324 "isSpatializationSupported = %{public}d, isHeadTrackingSupported = %{public}d",
325 audioSpatialDeviceState.isSpatializationSupported, audioSpatialDeviceState.isHeadTrackingSupported);
326 {
327 std::string encryptedAddress = GetSha256EncryptAddress(audioSpatialDeviceState.address);
328 std::lock_guard<std::mutex> lock(spatializationSupportedMutex_);
329 if (addressToSpatialDeviceStateMap_.count(encryptedAddress) > 0 &&
330 IsAudioSpatialDeviceStateEqual(addressToSpatialDeviceStateMap_[encryptedAddress],
331 audioSpatialDeviceState)) {
332 AUDIO_INFO_LOG("no need to UpdateSpatialDeviceState");
333 return SPATIALIZATION_SERVICE_OK;
334 }
335 addressToSpatialDeviceStateMap_[encryptedAddress] = audioSpatialDeviceState;
336 }
337
338 AUDIO_INFO_LOG("currSpatialDeviceType_ = %{public}d, nextSpatialDeviceType_ = %{public}d",
339 currSpatialDeviceType_, audioSpatialDeviceState.spatialDeviceType);
340 if (audioSpatialDeviceState.spatialDeviceType != currSpatialDeviceType_) {
341 UpdateSpatialDeviceType(audioSpatialDeviceState.spatialDeviceType);
342 currSpatialDeviceType_ = audioSpatialDeviceState.spatialDeviceType;
343 }
344
345 std::lock_guard<std::mutex> lock(spatializationServiceMutex_);
346 if (UpdateSpatializationStateReal(false) != 0) {
347 return ERROR;
348 }
349 return SPATIALIZATION_SERVICE_OK;
350 }
351
RegisterSpatializationStateEventListener(const uint32_t sessionID,const StreamUsage streamUsage,const sptr<IRemoteObject> & object)352 int32_t AudioSpatializationService::RegisterSpatializationStateEventListener(const uint32_t sessionID,
353 const StreamUsage streamUsage, const sptr<IRemoteObject> &object)
354 {
355 std::lock_guard<std::mutex> lock(spatializationStateChangeListnerMutex_);
356 CHECK_AND_RETURN_RET_LOG(object != nullptr, ERR_INVALID_PARAM,
357 "set spatialization state event listener object is nullptr");
358 sptr<IStandardSpatializationStateChangeListener> listener =
359 iface_cast<IStandardSpatializationStateChangeListener>(object);
360 CHECK_AND_RETURN_RET_LOG(listener != nullptr, ERR_INVALID_PARAM, "spatialization state obj cast failed");
361
362 std::shared_ptr<AudioSpatializationStateChangeCallback> callback =
363 std::make_shared<AudioSpatializationStateChangeListenerCallback>(listener);
364 CHECK_AND_RETURN_RET_LOG(callback != nullptr, ERR_INVALID_PARAM,
365 "failed to create spatialization state cb obj");
366
367 spatializationStateCBMap_[sessionID] = std::make_pair(callback, streamUsage);
368 return SUCCESS;
369 }
370
UnregisterSpatializationStateEventListener(const uint32_t sessionID)371 int32_t AudioSpatializationService::UnregisterSpatializationStateEventListener(const uint32_t sessionID)
372 {
373 std::lock_guard<std::mutex> lock(spatializationStateChangeListnerMutex_);
374 spatializationStateCBMap_.erase(sessionID);
375 return SUCCESS;
376 }
377
UpdateCurrentDevice(const std::string macAddress)378 void AudioSpatializationService::UpdateCurrentDevice(const std::string macAddress)
379 {
380 AUDIO_INFO_LOG("UpdateCurrentDevice Entered");
381 std::lock_guard<std::mutex> lock(spatializationServiceMutex_);
382 if (!macAddress.empty()) {
383 std::string deviceSpatialInfo = EncapsulateDeviceInfo(macAddress);
384 UpdateDeviceSpatialMapInfo(macAddress, deviceSpatialInfo);
385 WriteSpatializationStateToDb(WRITE_DEVICESPATIAL_INFO, macAddress);
386 }
387 if (currentDeviceAddress_ == macAddress) {
388 AUDIO_INFO_LOG("no need to UpdateCurrentDevice");
389 return;
390 }
391 std::string preDeviceAddress = currentDeviceAddress_;
392 currentDeviceAddress_ = macAddress;
393 std::string currEncryptedAddress_ = GetSha256EncryptAddress(currentDeviceAddress_);
394 if (addressToSpatialDeviceStateMap_.find(currEncryptedAddress_) != addressToSpatialDeviceStateMap_.end()) {
395 auto nextSpatialDeviceType{ addressToSpatialDeviceStateMap_[currEncryptedAddress_].spatialDeviceType };
396 AUDIO_INFO_LOG("currSpatialDeviceType_ = %{public}d, nextSpatialDeviceType_ = %{public}d",
397 currSpatialDeviceType_, nextSpatialDeviceType);
398 if (nextSpatialDeviceType != currSpatialDeviceType_) {
399 UpdateSpatialDeviceType(nextSpatialDeviceType);
400 currSpatialDeviceType_ = nextSpatialDeviceType;
401 }
402 } else {
403 AUDIO_INFO_LOG("currSpatialDeviceType_ = %{public}d, nextSpatialDeviceType_ = %{public}d",
404 currSpatialDeviceType_, EARPHONE_TYPE_NONE);
405 if (currSpatialDeviceType_ != EARPHONE_TYPE_NONE) {
406 UpdateSpatialDeviceType(EARPHONE_TYPE_NONE);
407 currSpatialDeviceType_ = EARPHONE_TYPE_NONE;
408 }
409 }
410
411 if (UpdateSpatializationStateReal(true, preDeviceAddress) != 0) {
412 AUDIO_WARNING_LOG("UpdateSpatializationStateReal fail");
413 }
414 }
415
GetSpatializationSceneType()416 AudioSpatializationSceneType AudioSpatializationService::GetSpatializationSceneType()
417 {
418 std::lock_guard<std::mutex> lock(spatializationServiceMutex_);
419 return spatializationSceneType_;
420 }
421
SetSpatializationSceneType(const AudioSpatializationSceneType spatializationSceneType)422 int32_t AudioSpatializationService::SetSpatializationSceneType(
423 const AudioSpatializationSceneType spatializationSceneType)
424 {
425 std::lock_guard<std::mutex> lock(spatializationServiceMutex_);
426 AUDIO_INFO_LOG("spatialization scene type is set to be %{public}d", spatializationSceneType);
427 spatializationSceneType_ = spatializationSceneType;
428 int32_t ret = UpdateSpatializationSceneType();
429 CHECK_AND_RETURN_RET_LOG(ret == SPATIALIZATION_SERVICE_OK, ret, "set spatialization scene type failed");
430 WriteSpatializationStateToDb(WRITE_SPATIALIZATION_SCENE);
431 return SPATIALIZATION_SERVICE_OK;
432 }
433
IsHeadTrackingDataRequested(const std::string & macAddress)434 bool AudioSpatializationService::IsHeadTrackingDataRequested(const std::string &macAddress)
435 {
436 std::lock_guard<std::mutex> lock(spatializationServiceMutex_);
437
438 if (macAddress != currentDeviceAddress_) {
439 return false;
440 }
441
442 return isHeadTrackingDataRequested_;
443 }
444
UpdateRendererInfo(const std::vector<std::unique_ptr<AudioRendererChangeInfo>> & rendererChangeInfo)445 void AudioSpatializationService::UpdateRendererInfo(
446 const std::vector<std::unique_ptr<AudioRendererChangeInfo>> &rendererChangeInfo)
447 {
448 AUDIO_DEBUG_LOG("Start");
449 {
450 std::lock_guard<std::mutex> lock(rendererInfoChangingMutex_);
451 AudioRendererInfoForSpatialization spatializationRendererInfo;
452
453 spatializationRendererInfoList_.clear();
454 for (const auto &it : rendererChangeInfo) {
455 spatializationRendererInfo.rendererState = it->rendererState;
456 spatializationRendererInfo.deviceMacAddress = it->outputDeviceInfo.macAddress;
457 spatializationRendererInfo.streamUsage = it->rendererInfo.streamUsage;
458 spatializationRendererInfoList_.push_back(spatializationRendererInfo);
459 }
460 }
461 std::lock_guard<std::mutex> lock(spatializationServiceMutex_);
462 UpdateHeadTrackingDeviceState(false);
463 }
464
UpdateSpatializationStateReal(bool outputDeviceChange,std::string preDeviceAddress)465 int32_t AudioSpatializationService::UpdateSpatializationStateReal(bool outputDeviceChange, std::string preDeviceAddress)
466 {
467 bool spatializationEnabled = false;
468 bool headTrackingEnabled = false;
469 std::string currEncryptedAddress_ = GetSha256EncryptAddress(currentDeviceAddress_);
470 if (preSettingSpatialAddress_ == "NO_PREVIOUS_SET_DEVICE") {
471 spatializationEnabled = spatializationStateFlag_.spatializationEnabled &&
472 IsSpatializationSupported() && IsSpatializationSupportedForDevice(currentDeviceAddress_);
473 headTrackingEnabled = spatializationStateFlag_.headTrackingEnabled && IsHeadTrackingSupported() &&
474 IsHeadTrackingSupportedForDevice(currentDeviceAddress_) && spatializationEnabled;
475 } else {
476 spatializationEnabled = addressToSpatialEnabledMap_[currEncryptedAddress_].spatializationEnabled &&
477 IsSpatializationSupported() && IsSpatializationSupportedForDevice(currentDeviceAddress_);
478 headTrackingEnabled = addressToSpatialEnabledMap_[currEncryptedAddress_].headTrackingEnabled &&
479 IsHeadTrackingSupported() && IsHeadTrackingSupportedForDevice(currentDeviceAddress_) &&
480 spatializationEnabled;
481 }
482
483 if ((spatializationEnabledReal_ == spatializationEnabled) && (headTrackingEnabledReal_ == headTrackingEnabled)) {
484 AUDIO_INFO_LOG("no need to update real spatialization state");
485 UpdateHeadTrackingDeviceState(outputDeviceChange, preDeviceAddress);
486 return SUCCESS;
487 }
488 spatializationEnabledReal_ = spatializationEnabled;
489 headTrackingEnabledReal_ = headTrackingEnabled;
490 if (UpdateSpatializationState() != 0) {
491 return ERROR;
492 }
493 HandleSpatializationStateChange(outputDeviceChange);
494 UpdateHeadTrackingDeviceState(outputDeviceChange, preDeviceAddress);
495 return SPATIALIZATION_SERVICE_OK;
496 }
497
UpdateSpatializationState()498 int32_t AudioSpatializationService::UpdateSpatializationState()
499 {
500 const sptr<IStandardAudioService> gsp = GetAudioServerProxy();
501 if (gsp == nullptr) {
502 AUDIO_ERR_LOG("Service proxy unavailable: g_adProxy null");
503 return -1;
504 }
505 AudioSpatializationState spatializationState = {spatializationEnabledReal_, headTrackingEnabledReal_};
506 std::string identity = IPCSkeleton::ResetCallingIdentity();
507 int32_t ret = gsp->UpdateSpatializationState(spatializationState);
508 IPCSkeleton::SetCallingIdentity(identity);
509 if (ret != 0) {
510 AUDIO_WARNING_LOG("UpdateSpatializationState fail");
511 }
512 return SPATIALIZATION_SERVICE_OK;
513 }
514
UpdateSpatializationSceneType()515 int32_t AudioSpatializationService::UpdateSpatializationSceneType()
516 {
517 const sptr<IStandardAudioService> gsp = GetAudioServerProxy();
518 if (gsp == nullptr) {
519 AUDIO_ERR_LOG("Service proxy unavailable: g_adProxy null");
520 return -1;
521 }
522 std::string identity = IPCSkeleton::ResetCallingIdentity();
523 int32_t ret = gsp->SetSpatializationSceneType(spatializationSceneType_);
524 IPCSkeleton::SetCallingIdentity(identity);
525 CHECK_AND_RETURN_RET_LOG(ret == SPATIALIZATION_SERVICE_OK, ret, "set spatialization scene type failed");
526 return SPATIALIZATION_SERVICE_OK;
527 }
528
UpdateDeviceSpatialInfo(const uint32_t deviceID,const std::string deviceSpatialInfo)529 void AudioSpatializationService::UpdateDeviceSpatialInfo(const uint32_t deviceID, const std::string deviceSpatialInfo)
530 {
531 std::stringstream ss(deviceSpatialInfo);
532 std::string token;
533 std::string address;
534 std::getline(ss, address, '|');
535 addressToDeviceSpatialInfoMap_[address] = deviceSpatialInfo;
536 addressToDeviceIDMap_[address] = deviceID;
537 std::getline(ss, token, '|');
538 addressToSpatialEnabledMap_[address].spatializationEnabled = std::stoi(token);
539 std::getline(ss, token, '|');
540 addressToSpatialEnabledMap_[address].headTrackingEnabled = std::stoi(token);
541 std::getline(ss, token, '|');
542 addressToSpatialDeviceStateMap_[address].isSpatializationSupported = std::stoi(token);
543 std::getline(ss, token, '|');
544 addressToSpatialDeviceStateMap_[address].isHeadTrackingSupported = std::stoi(token);
545 std::getline(ss, token, '|');
546 addressToSpatialDeviceStateMap_[address].spatialDeviceType = static_cast<AudioSpatialDeviceType>(std::stoi(token));
547 }
548
UpdateSpatialDeviceType(AudioSpatialDeviceType spatialDeviceType)549 void AudioSpatializationService::UpdateSpatialDeviceType(AudioSpatialDeviceType spatialDeviceType)
550 {
551 const sptr<IStandardAudioService> gsp = GetAudioServerProxy();
552 CHECK_AND_RETURN_LOG(gsp != nullptr, "Service proxy unavailable: g_adProxy null");
553
554 std::string identity = IPCSkeleton::ResetCallingIdentity();
555 int32_t ret = gsp->UpdateSpatialDeviceType(spatialDeviceType);
556 IPCSkeleton::SetCallingIdentity(identity);
557 CHECK_AND_RETURN_LOG(ret == 0, "AudioSpatializationService::UpdateSpatialDeviceType fail");
558
559 return;
560 }
561
HandleSpatializationStateChange(bool outputDeviceChange)562 void AudioSpatializationService::HandleSpatializationStateChange(bool outputDeviceChange)
563 {
564 AUDIO_INFO_LOG("Spatialization State callback is triggered");
565 std::lock_guard<std::mutex> lock(spatializationStateChangeListnerMutex_);
566
567 AudioSpatializationState spatializationState = {spatializationEnabledReal_, headTrackingEnabledReal_};
568 AudioSpatializationState spatializationNotSupported = {false, false};
569 std::unordered_map<uint32_t, bool> sessionIDToSpatializationEnabledMap;
570
571 for (auto it = spatializationStateCBMap_.begin(); it != spatializationStateCBMap_.end(); ++it) {
572 std::shared_ptr<AudioSpatializationStateChangeCallback> spatializationStateChangeCb = (it->second).first;
573 if (spatializationStateChangeCb == nullptr) {
574 AUDIO_ERR_LOG("spatializationStateChangeCb : nullptr for sessionID : %{public}d",
575 static_cast<int32_t>(it->first));
576 it = spatializationStateCBMap_.erase(it);
577 continue;
578 }
579 if (!IsSpatializationSupportedUsage((it->second).second)) {
580 if (!outputDeviceChange) {
581 sessionIDToSpatializationEnabledMap.insert(std::make_pair(it->first, false));
582 }
583 spatializationStateChangeCb->OnSpatializationStateChange(spatializationNotSupported);
584 } else {
585 if (!outputDeviceChange) {
586 sessionIDToSpatializationEnabledMap.insert(std::make_pair(it->first, spatializationEnabledReal_));
587 }
588 spatializationStateChangeCb->OnSpatializationStateChange(spatializationState);
589 }
590 }
591
592 if (!outputDeviceChange) {
593 AUDIO_INFO_LOG("notify offload entered");
594 std::thread notifyOffloadThread = std::thread([=] () mutable {
595 AudioPolicyService::GetAudioPolicyService().UpdateA2dpOffloadFlagBySpatialService(currentDeviceAddress_,
596 sessionIDToSpatializationEnabledMap);
597 });
598 notifyOffloadThread.detach();
599 }
600 }
601
InitSpatializationState()602 void AudioSpatializationService::InitSpatializationState()
603 {
604 std::lock_guard<std::mutex> lock(spatializationServiceMutex_);
605 CHECK_AND_RETURN_LOG(!isLoadedfromDb_, "the spatialization values have already been loaded");
606 int32_t pack = 0;
607 int32_t sceneType = 0;
608 std::string deviceSpatialInfo;
609
610 AudioSettingProvider &settingProvider = AudioSettingProvider::GetInstance(AUDIO_POLICY_SERVICE_ID);
611 ErrCode ret = settingProvider.GetIntValue(SPATIALIZATION_STATE_SETTINGKEY, pack);
612 if (ret != SUCCESS) {
613 AUDIO_WARNING_LOG("Failed to read spatialization_state from setting db! Err: %{public}d", ret);
614 WriteSpatializationStateToDb(WRITE_SPATIALIZATION_STATE);
615 } else {
616 UnpackSpatializationState(pack, spatializationStateFlag_);
617 UpdateSpatializationStateReal(false);
618 }
619
620 ret = settingProvider.GetIntValue(SPATIALIZATION_SCENE_SETTINGKEY, sceneType);
621 if (ret != SUCCESS || sceneType < SPATIALIZATION_SCENE_TYPE_DEFAULT || sceneType > SPATIALIZATION_SCENE_TYPE_MAX) {
622 AUDIO_WARNING_LOG("Failed to read spatialization_scene from setting db! Err: %{public}d", ret);
623 WriteSpatializationStateToDb(WRITE_SPATIALIZATION_SCENE);
624 } else {
625 spatializationSceneType_ = static_cast<AudioSpatializationSceneType>(sceneType);
626 UpdateSpatializationSceneType();
627 }
628
629 for (uint32_t i = 1; i <= MAX_DEVICE_NUM; ++i) {
630 ret = settingProvider.GetStringValue(SPATIALIZATION_STATE_SETTINGKEY + "_device" + std::to_string(i),
631 deviceSpatialInfo);
632 if (ret != SUCCESS) {
633 AUDIO_DEBUG_LOG("Failed to read spatialization_state_device%{public}d from setting db! Err: %{public}d",
634 i, ret);
635 break;
636 }
637 UpdateDeviceSpatialInfo(i, deviceSpatialInfo);
638 }
639
640 ret = settingProvider.GetStringValue(PRE_SETTING_SPATIAL_ADDRESS, preSettingSpatialAddress_);
641 if (ret != SUCCESS) {
642 AUDIO_WARNING_LOG("Failed to read pre_setting_spatial_address from setting db! Err: %{public}d", ret);
643 preSettingSpatialAddress_ = "NO_PREVIOUS_SET_DEVICE";
644 }
645 UpdateSpatializationStateReal(false);
646 isLoadedfromDb_ = true;
647 }
648
WriteSpatializationStateToDb(WriteToDbOperation operation,const std::string address)649 void AudioSpatializationService::WriteSpatializationStateToDb(WriteToDbOperation operation, const std::string address)
650 {
651 AudioSettingProvider &settingProvider = AudioSettingProvider::GetInstance(AUDIO_POLICY_SERVICE_ID);
652 switch (operation) {
653 case WRITE_SPATIALIZATION_STATE: {
654 ErrCode ret = settingProvider.PutIntValue(
655 SPATIALIZATION_STATE_SETTINGKEY, PackSpatializationState(spatializationStateFlag_));
656 CHECK_AND_RETURN_LOG(ret == SUCCESS, "Failed to write spatialization_state to setting db: %{public}d", ret);
657 break;
658 }
659 case WRITE_SPATIALIZATION_SCENE: {
660 ErrCode ret = settingProvider.PutIntValue(
661 SPATIALIZATION_SCENE_SETTINGKEY, static_cast<uint32_t>(spatializationSceneType_));
662 CHECK_AND_RETURN_LOG(ret == SUCCESS, "Failed to write spatialization_scene to setting db: %{public}d", ret);
663 break;
664 }
665 case WRITE_DEVICESPATIAL_INFO: {
666 std::string encryptedAddress = GetSha256EncryptAddress(address);
667 uint32_t tmpID = addressToDeviceIDMap_[encryptedAddress];
668 ErrCode ret = settingProvider.PutStringValue(SPATIALIZATION_STATE_SETTINGKEY + "_device" +
669 std::to_string(tmpID), addressToDeviceSpatialInfoMap_[encryptedAddress]);
670 CHECK_AND_RETURN_LOG(ret == SUCCESS, "Failed to write spatialization_state_device%{public}d to"
671 "setting db: %{public}d", tmpID, ret);
672 ret = settingProvider.PutStringValue(PRE_SETTING_SPATIAL_ADDRESS, preSettingSpatialAddress_);
673 CHECK_AND_RETURN_LOG(ret == SUCCESS, "Failed to write pre_setting_spatial_address to"
674 "setting db: %{public}d", ret);
675 break;
676 }
677 default:
678 break;
679 }
680 }
681
IsHeadTrackingDataRequestedForCurrentDevice()682 bool AudioSpatializationService::IsHeadTrackingDataRequestedForCurrentDevice()
683 {
684 std::lock_guard<std::mutex> lock(rendererInfoChangingMutex_);
685 bool isStreamRunning = false;
686 for (const auto &rendererInfo : spatializationRendererInfoList_) {
687 if (rendererInfo.rendererState == RENDERER_RUNNING && rendererInfo.deviceMacAddress == currentDeviceAddress_ &&
688 IsSpatializationSupportedUsage(rendererInfo.streamUsage)) {
689 isStreamRunning = true;
690 break;
691 }
692 }
693 return (isStreamRunning && headTrackingEnabledReal_);
694 }
695
UpdateHeadTrackingDeviceState(bool outputDeviceChange,std::string preDeviceAddress)696 void AudioSpatializationService::UpdateHeadTrackingDeviceState(bool outputDeviceChange, std::string preDeviceAddress)
697 {
698 std::unordered_map<std::string, bool> headTrackingDeviceChangeInfo;
699 if (outputDeviceChange && !preDeviceAddress.empty() && isHeadTrackingDataRequested_) {
700 headTrackingDeviceChangeInfo.insert(std::make_pair(preDeviceAddress, false));
701 }
702
703 bool isRequested = IsHeadTrackingDataRequestedForCurrentDevice();
704 if (!currentDeviceAddress_.empty() &&
705 ((!outputDeviceChange && (isHeadTrackingDataRequested_ != isRequested)) ||
706 (outputDeviceChange && isRequested))) {
707 headTrackingDeviceChangeInfo.insert(std::make_pair(currentDeviceAddress_, isRequested));
708 }
709
710 isHeadTrackingDataRequested_ = isRequested;
711
712 HandleHeadTrackingDeviceChange(headTrackingDeviceChangeInfo);
713 }
714
HandleHeadTrackingDeviceChange(const std::unordered_map<std::string,bool> & changeInfo)715 void AudioSpatializationService::HandleHeadTrackingDeviceChange(const std::unordered_map<std::string, bool> &changeInfo)
716 {
717 AUDIO_DEBUG_LOG("callback is triggered, change info size is %{public}zu", changeInfo.size());
718
719 if (changeInfo.size() == 0) {
720 return;
721 }
722
723 if (audioPolicyServerHandler_ != nullptr) {
724 audioPolicyServerHandler_->SendHeadTrackingDeviceChangeEvent(changeInfo);
725 }
726 }
727
GetCurrentDeviceAddress() const728 std::string AudioSpatializationService::GetCurrentDeviceAddress() const
729 {
730 return currentDeviceAddress_;
731 }
732
GetCurrTimestamp()733 std::string AudioSpatializationService::GetCurrTimestamp()
734 {
735 std::time_t now = std::time(nullptr);
736 std::ostringstream oss;
737 oss << now;
738 return oss.str();
739 }
740
GetSha256EncryptAddress(const std::string & address)741 std::string AudioSpatializationService::GetSha256EncryptAddress(const std::string& address)
742 {
743 const int32_t HexWidth = 2;
744 unsigned char hash[SHA256_DIGEST_LENGTH];
745 SHA256(reinterpret_cast<const unsigned char *>(address.c_str()), address.size(), hash);
746 std::stringstream ss;
747 for (int32_t i = 0; i < SHA256_DIGEST_LENGTH; ++i) {
748 ss << std::hex << std::setw(HexWidth) << std::setfill('0') << (int32_t)hash[i];
749 }
750 return ss.str();
751 }
752
ExtractTimestamp(const std::string deviceSpatialInfo)753 std::string AudioSpatializationService::ExtractTimestamp(const std::string deviceSpatialInfo)
754 {
755 size_t pos = deviceSpatialInfo.rfind("|");
756 if (pos != std::string::npos) {
757 return deviceSpatialInfo.substr(pos + 1);
758 }
759 return "";
760 }
761
EncapsulateDeviceInfo(const std::string address)762 std::string AudioSpatializationService::EncapsulateDeviceInfo(const std::string address)
763 {
764 std::stringstream value;
765 std::string encryptedAddress = GetSha256EncryptAddress(address);
766 value << encryptedAddress;
767 value << "|" << addressToSpatialEnabledMap_[encryptedAddress].spatializationEnabled;
768 value << "|" << addressToSpatialEnabledMap_[encryptedAddress].headTrackingEnabled;
769 value << "|" << addressToSpatialDeviceStateMap_[encryptedAddress].isSpatializationSupported;
770 value << "|" << addressToSpatialDeviceStateMap_[encryptedAddress].isHeadTrackingSupported;
771 value << "|" << addressToSpatialDeviceStateMap_[encryptedAddress].spatialDeviceType;
772 value << "|" << GetCurrTimestamp();
773 return value.str();
774 }
775
RemoveOldestDevice()776 std::string AudioSpatializationService::RemoveOldestDevice()
777 {
778 std::string oldestAddr = "";
779 std::string oldestTimestamp = "";
780 for (const auto& entry : addressToDeviceSpatialInfoMap_) {
781 std::string currTimestamp = ExtractTimestamp(entry.second);
782 if (oldestTimestamp.empty() || std::stoul(currTimestamp) < std::stoul(oldestTimestamp)) {
783 oldestTimestamp = currTimestamp;
784 oldestAddr = entry.first;
785 }
786 }
787 addressToDeviceSpatialInfoMap_.erase(oldestAddr);
788 addressToSpatialEnabledMap_.erase(oldestAddr);
789 addressToSpatialDeviceStateMap_.erase(oldestAddr);
790 return oldestAddr;
791 }
792
UpdateDeviceSpatialMapInfo(std::string address,std::string deviceSpatialInfo)793 void AudioSpatializationService::UpdateDeviceSpatialMapInfo(std::string address, std::string deviceSpatialInfo)
794 {
795 std::string encryptedAddress = GetSha256EncryptAddress(address);
796 if (!addressToDeviceSpatialInfoMap_.count(encryptedAddress)) {
797 if (addressToDeviceSpatialInfoMap_.size() >= MAX_DEVICE_NUM) {
798 std::string oldestAddr = RemoveOldestDevice();
799 addressToDeviceIDMap_[encryptedAddress] = addressToDeviceIDMap_[oldestAddr];
800 } else {
801 addressToDeviceIDMap_[encryptedAddress] = addressToDeviceSpatialInfoMap_.size() + 1;
802 }
803 }
804 addressToDeviceSpatialInfoMap_[encryptedAddress] = deviceSpatialInfo;
805 }
806 } // namespace AudioStandard
807 } // namespace OHOS
808