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.h"
25 #include "audio_spatialization_state_change_callback.h"
26 #include "audio_policy_service.h"
27 #include "audio_setting_provider.h"
28 #include "istandard_audio_service.h"
29
30 namespace OHOS {
31 namespace AudioStandard {
32 using namespace std;
33
34 static const int32_t SPATIALIZATION_SERVICE_OK = 0;
35 static const std::string BLUETOOTH_EFFECT_CHAIN_NAME = "EFFECTCHAIN_BT_MUSIC";
36 static const std::string SPATIALIZATION_AND_HEAD_TRACKING_SUPPORTED_LABEL = "SPATIALIZATION_AND_HEADTRACKING";
37 static const std::string SPATIALIZATION_SUPPORTED_LABEL = "SPATIALIZATION";
38 static const std::string HEAD_TRACKING_SUPPORTED_LABEL = "HEADTRACKING";
39 static const std::string SPATIALIZATION_STATE_SETTINGKEY = "spatialization_state";
40 static const std::string SPATIALIZATION_SCENE_SETTINGKEY = "spatialization_scene";
41 static const std::string PRE_SETTING_SPATIAL_ADDRESS = "pre_setting_spatial_address";
42 static sptr<IStandardAudioService> g_adProxy = nullptr;
43 mutex g_adSpatializationProxyMutex;
44
45 enum SpatializationStateOffset {
46 SPATIALIZATION_OFFSET,
47 HEADTRACKING_OFFSET
48 };
49
UnpackSpatializationState(uint32_t pack,AudioSpatializationState & state)50 static void UnpackSpatializationState(uint32_t pack, AudioSpatializationState &state)
51 {
52 state = {(pack >> SPATIALIZATION_OFFSET) & 1, (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
InitSpatializationScene()629 int32_t AudioSpatializationService::InitSpatializationScene()
630 {
631 int32_t sceneType = 0;
632 AudioSettingProvider &settingProvider = AudioSettingProvider::GetInstance(AUDIO_POLICY_SERVICE_ID);
633 ErrCode ret = settingProvider.GetIntValue(SPATIALIZATION_SCENE_SETTINGKEY, sceneType);
634 CHECK_AND_RETURN_RET_LOG(ret != ERR_NO_INIT, ERROR, "database not initialized");
635 if (ret != SUCCESS || sceneType < SPATIALIZATION_SCENE_TYPE_DEFAULT ||
636 sceneType > SPATIALIZATION_SCENE_TYPE_MAX) {
637 AUDIO_WARNING_LOG("Failed to read spatialization_scene from setting db! Err: %{public}d", ret);
638 WriteSpatializationStateToDb(WRITE_SPATIALIZATION_SCENE);
639 } else {
640 spatializationSceneType_ = static_cast<AudioSpatializationSceneType>(sceneType);
641 UpdateSpatializationSceneType();
642 }
643 return SUCCESS;
644 }
645
InitSpatializationState()646 void AudioSpatializationService::InitSpatializationState()
647 {
648 std::map<std::string, uint32_t> tmpAddressToDeviceIDMap;
649 {
650 std::lock_guard<std::mutex> lock(spatializationServiceMutex_);
651 CHECK_AND_RETURN_LOG(!isLoadedfromDb_, "the spatialization values have already been loaded");
652 int32_t pack = 0;
653 std::string deviceSpatialInfo;
654
655 AudioSettingProvider &settingProvider = AudioSettingProvider::GetInstance(AUDIO_POLICY_SERVICE_ID);
656 ErrCode ret = settingProvider.GetIntValue(SPATIALIZATION_STATE_SETTINGKEY, pack);
657 CHECK_AND_RETURN_LOG(ret != ERR_NO_INIT, "database not initialized");
658 if (ret != SUCCESS) {
659 AUDIO_WARNING_LOG("Failed to read spatialization_state from setting db! Err: %{public}d", ret);
660 WriteSpatializationStateToDb(WRITE_SPATIALIZATION_STATE);
661 } else {
662 UnpackSpatializationState(pack, spatializationStateFlag_);
663 UpdateSpatializationStateReal(false);
664 }
665
666 CHECK_AND_RETURN(InitSpatializationScene() == SUCCESS);
667
668 for (uint32_t i = 1; i <= MAX_DEVICE_NUM; ++i) {
669 ret = settingProvider.GetStringValue(SPATIALIZATION_STATE_SETTINGKEY + "_device" + std::to_string(i),
670 deviceSpatialInfo);
671 CHECK_AND_RETURN_LOG(ret != ERR_NO_INIT, "database not initialized");
672 if (ret != SUCCESS) {
673 AUDIO_DEBUG_LOG("Failed to read spatialization_state_device%{public}d from setting db! Err: %{public}d",
674 i, ret);
675 break;
676 }
677 UpdateDeviceSpatialInfo(i, deviceSpatialInfo);
678 }
679 tmpAddressToDeviceIDMap = addressToDeviceIDMap_;
680
681 ret = settingProvider.GetStringValue(PRE_SETTING_SPATIAL_ADDRESS, preSettingSpatialAddress_);
682 CHECK_AND_RETURN_LOG(ret != ERR_NO_INIT, "database not initialized");
683 if (ret != SUCCESS) {
684 AUDIO_WARNING_LOG("Failed to read pre_setting_spatial_address from setting db! Err: %{public}d", ret);
685 preSettingSpatialAddress_ = "NO_PREVIOUS_SET_DEVICE";
686 }
687 UpdateSpatializationStateReal(false);
688 isLoadedfromDb_ = true;
689 }
690 for (auto it = tmpAddressToDeviceIDMap.begin(); it != tmpAddressToDeviceIDMap.end(); ++it) {
691 UpdateSpatializationSupported(it->first);
692 }
693 }
694
WriteSpatializationStateToDb(WriteToDbOperation operation,const std::string address)695 void AudioSpatializationService::WriteSpatializationStateToDb(WriteToDbOperation operation, const std::string address)
696 {
697 AudioSettingProvider &settingProvider = AudioSettingProvider::GetInstance(AUDIO_POLICY_SERVICE_ID);
698 switch (operation) {
699 case WRITE_SPATIALIZATION_STATE: {
700 ErrCode ret = settingProvider.PutIntValue(
701 SPATIALIZATION_STATE_SETTINGKEY, PackSpatializationState(spatializationStateFlag_));
702 CHECK_AND_RETURN_LOG(ret == SUCCESS,
703 "Failed to write spatialization_state to setting db: %{public}d", ret);
704 break;
705 }
706 case WRITE_SPATIALIZATION_SCENE: {
707 ErrCode ret = settingProvider.PutIntValue(
708 SPATIALIZATION_SCENE_SETTINGKEY, static_cast<uint32_t>(spatializationSceneType_));
709 CHECK_AND_RETURN_LOG(ret == SUCCESS,
710 "Failed to write spatialization_scene to setting db: %{public}d", ret);
711 break;
712 }
713 case WRITE_DEVICESPATIAL_INFO: {
714 std::string encryptedAddress = GetSha256EncryptAddress(address);
715 uint32_t tmpID = addressToDeviceIDMap_[encryptedAddress];
716 ErrCode ret = settingProvider.PutStringValue(SPATIALIZATION_STATE_SETTINGKEY + "_device" +
717 std::to_string(tmpID), addressToDeviceSpatialInfoMap_[encryptedAddress]);
718 CHECK_AND_RETURN_LOG(ret == SUCCESS, "Failed to write spatialization_state_device%{public}d to"
719 "setting db: %{public}d", tmpID, ret);
720 ret = settingProvider.PutStringValue(PRE_SETTING_SPATIAL_ADDRESS, preSettingSpatialAddress_);
721 CHECK_AND_RETURN_LOG(ret == SUCCESS, "Failed to write pre_setting_spatial_address to"
722 "setting db: %{public}d", ret);
723 break;
724 }
725 default:
726 break;
727 }
728 }
729
IsHeadTrackingDataRequestedForCurrentDevice()730 bool AudioSpatializationService::IsHeadTrackingDataRequestedForCurrentDevice()
731 {
732 std::lock_guard<std::mutex> lock(rendererInfoChangingMutex_);
733 bool isStreamRunning = false;
734 for (const auto &rendererInfo : spatializationRendererInfoList_) {
735 if (rendererInfo.rendererState == RENDERER_RUNNING && rendererInfo.deviceMacAddress == currentDeviceAddress_ &&
736 IsSpatializationSupportedUsage(rendererInfo.streamUsage)) {
737 isStreamRunning = true;
738 break;
739 }
740 }
741 return (isStreamRunning && headTrackingEnabledReal_);
742 }
743
UpdateHeadTrackingDeviceState(bool outputDeviceChange,std::string preDeviceAddress)744 void AudioSpatializationService::UpdateHeadTrackingDeviceState(bool outputDeviceChange, std::string preDeviceAddress)
745 {
746 std::unordered_map<std::string, bool> headTrackingDeviceChangeInfo;
747 if (outputDeviceChange && !preDeviceAddress.empty() && isHeadTrackingDataRequested_) {
748 headTrackingDeviceChangeInfo.insert(std::make_pair(preDeviceAddress, false));
749 }
750
751 bool isRequested = IsHeadTrackingDataRequestedForCurrentDevice();
752 if (!currentDeviceAddress_.empty() &&
753 ((!outputDeviceChange && (isHeadTrackingDataRequested_ != isRequested)) ||
754 (outputDeviceChange && isRequested))) {
755 headTrackingDeviceChangeInfo.insert(std::make_pair(currentDeviceAddress_, isRequested));
756 }
757
758 isHeadTrackingDataRequested_ = isRequested;
759
760 HandleHeadTrackingDeviceChange(headTrackingDeviceChangeInfo);
761 }
762
HandleHeadTrackingDeviceChange(const std::unordered_map<std::string,bool> & changeInfo)763 void AudioSpatializationService::HandleHeadTrackingDeviceChange(
764 const std::unordered_map<std::string, bool> &changeInfo)
765 {
766 AUDIO_DEBUG_LOG("callback is triggered, change info size is %{public}zu", changeInfo.size());
767
768 if (changeInfo.size() == 0) {
769 return;
770 }
771
772 if (audioPolicyServerHandler_ != nullptr) {
773 audioPolicyServerHandler_->SendHeadTrackingDeviceChangeEvent(changeInfo);
774 }
775 }
776
UpdateSpatializationSupported(const std::string encryptedAddress)777 void AudioSpatializationService::UpdateSpatializationSupported(const std::string encryptedAddress)
778 {
779 if (!addressToSpatialDeviceStateMap_.count(encryptedAddress)) {
780 AUDIO_INFO_LOG("specified address for spatialization is not in memory");
781 return;
782 }
783 AudioPolicyService::GetAudioPolicyService().UpdateSpatializationSupported(encryptedAddress,
784 addressToSpatialDeviceStateMap_[encryptedAddress].isSpatializationSupported && isSpatializationSupported_);
785 }
786
GetCurrentDeviceAddress() const787 std::string AudioSpatializationService::GetCurrentDeviceAddress() const
788 {
789 return currentDeviceAddress_;
790 }
791
GetCurrTimestamp()792 std::string AudioSpatializationService::GetCurrTimestamp()
793 {
794 std::time_t now = std::time(nullptr);
795 std::ostringstream oss;
796 oss << now;
797 return oss.str();
798 }
799
GetSha256EncryptAddress(const std::string & address)800 std::string AudioSpatializationService::GetSha256EncryptAddress(const std::string& address)
801 {
802 const int32_t HexWidth = 2;
803 unsigned char hash[SHA256_DIGEST_LENGTH];
804 SHA256(reinterpret_cast<const unsigned char *>(address.c_str()), address.size(), hash);
805 std::stringstream ss;
806 for (int32_t i = 0; i < SHA256_DIGEST_LENGTH; ++i) {
807 ss << std::hex << std::setw(HexWidth) << std::setfill('0') << (int32_t)hash[i];
808 }
809 return ss.str();
810 }
811
ExtractTimestamp(const std::string deviceSpatialInfo)812 std::string AudioSpatializationService::ExtractTimestamp(const std::string deviceSpatialInfo)
813 {
814 size_t pos = deviceSpatialInfo.rfind("|");
815 if (pos != std::string::npos) {
816 return deviceSpatialInfo.substr(pos + 1);
817 }
818 return "";
819 }
820
EncapsulateDeviceInfo(const std::string address)821 std::string AudioSpatializationService::EncapsulateDeviceInfo(const std::string address)
822 {
823 std::stringstream value;
824 std::string encryptedAddress = GetSha256EncryptAddress(address);
825 value << encryptedAddress;
826 value << "|" << addressToSpatialEnabledMap_[encryptedAddress].spatializationEnabled;
827 value << "|" << addressToSpatialEnabledMap_[encryptedAddress].headTrackingEnabled;
828 value << "|" << addressToSpatialDeviceStateMap_[encryptedAddress].isSpatializationSupported;
829 value << "|" << addressToSpatialDeviceStateMap_[encryptedAddress].isHeadTrackingSupported;
830 value << "|" << addressToSpatialDeviceStateMap_[encryptedAddress].spatialDeviceType;
831 value << "|" << GetCurrTimestamp();
832 return value.str();
833 }
834
RemoveOldestDevice()835 std::string AudioSpatializationService::RemoveOldestDevice()
836 {
837 std::string oldestAddr = "";
838 std::string oldestTimestamp = "";
839 for (const auto& entry : addressToDeviceSpatialInfoMap_) {
840 std::string currTimestamp = ExtractTimestamp(entry.second);
841 if (oldestTimestamp.empty() || std::stoul(currTimestamp) < std::stoul(oldestTimestamp)) {
842 oldestTimestamp = currTimestamp;
843 oldestAddr = entry.first;
844 }
845 }
846 addressToDeviceSpatialInfoMap_.erase(oldestAddr);
847 addressToSpatialEnabledMap_.erase(oldestAddr);
848 addressToSpatialDeviceStateMap_.erase(oldestAddr);
849 return oldestAddr;
850 }
851
UpdateDeviceSpatialMapInfo(std::string address,std::string deviceSpatialInfo)852 void AudioSpatializationService::UpdateDeviceSpatialMapInfo(std::string address, std::string deviceSpatialInfo)
853 {
854 std::string encryptedAddress = GetSha256EncryptAddress(address);
855 if (!addressToDeviceSpatialInfoMap_.count(encryptedAddress)) {
856 if (addressToDeviceSpatialInfoMap_.size() >= MAX_DEVICE_NUM) {
857 std::string oldestAddr = RemoveOldestDevice();
858 addressToDeviceIDMap_[encryptedAddress] = addressToDeviceIDMap_[oldestAddr];
859 } else {
860 addressToDeviceIDMap_[encryptedAddress] = addressToDeviceSpatialInfoMap_.size() + 1;
861 }
862 }
863 addressToDeviceSpatialInfoMap_[encryptedAddress] = deviceSpatialInfo;
864 }
865 } // namespace AudioStandard
866 } // namespace OHOS
867