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