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