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