1 /*
2 * Copyright (c) 2021-2025 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 "AudioOffloadStream"
17 #endif
18
19 #include "audio_offload_stream.h"
20 #include <ability_manager_client.h>
21 #include "iservice_registry.h"
22 #include "parameter.h"
23 #include "parameters.h"
24 #include "audio_policy_log.h"
25 #include "media_monitor_manager.h"
26 #include "audio_spatialization_service.h"
27
28 #include "audio_policy_utils.h"
29 #include "audio_server_proxy.h"
30
31 namespace OHOS {
32 namespace AudioStandard {
33
34 const int32_t UID_AUDIO = 1041;
35 const int32_t dAudioClientUid = 3055;
36 static const int32_t WAIT_OFFLOAD_CLOSE_TIME_S = 10; // 10s
37 static const int32_t SELECT_PIPE_TYPE_OFFLOAD_MUTE_US = 200000; // 200ms
38
PrintSinkInput(SinkInput sinkInput)39 inline std::string PrintSinkInput(SinkInput sinkInput)
40 {
41 std::stringstream value;
42 value << "streamId:[" << sinkInput.streamId << "] ";
43 value << "streamType:[" << sinkInput.streamType << "] ";
44 value << "uid:[" << sinkInput.uid << "] ";
45 value << "pid:[" << sinkInput.pid << "] ";
46 value << "statusMark:[" << sinkInput.statusMark << "] ";
47 value << "sinkName:[" << sinkInput.sinkName << "] ";
48 value << "startTime:[" << sinkInput.startTime << "]";
49 return value.str();
50 }
51
HandlePowerStateChanged(PowerMgr::PowerState state)52 void AudioOffloadStream::HandlePowerStateChanged(PowerMgr::PowerState state)
53 {
54 if (currentPowerState_ == state) {
55 return;
56 }
57 currentPowerState_ = state;
58 if (!audioActiveDevice_.CheckActiveOutputDeviceSupportOffload()) {
59 return;
60 }
61 if (offloadSessionID_.has_value()) {
62 AUDIO_DEBUG_LOG("SetOffloadMode! Offload power is state = %{public}d", state);
63 SetOffloadMode();
64 }
65 }
66
SetOffloadAvailableFromXML(AudioModuleInfo & moduleInfo)67 void AudioOffloadStream::SetOffloadAvailableFromXML(AudioModuleInfo &moduleInfo)
68 {
69 isOffloadAvailable_ = true;
70 }
71
GetOffloadAvailableFromXml() const72 bool AudioOffloadStream::GetOffloadAvailableFromXml() const
73 {
74 return isOffloadAvailable_;
75 }
76
SetOffloadMode()77 void AudioOffloadStream::SetOffloadMode()
78 {
79 if (!GetOffloadAvailableFromXml()) {
80 AUDIO_INFO_LOG("Offload not available, skipped");
81 return;
82 }
83
84 AUDIO_INFO_LOG("sessionId: %{public}d, PowerState: %{public}d, isAppBack: %{public}d",
85 *offloadSessionID_, static_cast<int32_t>(currentPowerState_), currentOffloadSessionIsBackground_);
86 AudioServerProxy::GetInstance().SetOffloadModeProxy(*offloadSessionID_, static_cast<int32_t>(currentPowerState_),
87 currentOffloadSessionIsBackground_);
88 }
89
OffloadStreamSetCheck(uint32_t sessionId)90 void AudioOffloadStream::OffloadStreamSetCheck(uint32_t sessionId)
91 {
92 AudioDeviceDescriptor deviceInfo(AudioDeviceDescriptor::DEVICE_INFO);
93 std::string curOutputNetworkId = audioActiveDevice_.GetCurrentOutputDeviceNetworkId();
94 std::string curOutputMacAddr = audioActiveDevice_.GetCurrentOutputDeviceMacAddr();
95 DeviceType curOutputDeviceType = audioActiveDevice_.GetCurrentOutputDeviceType();
96 streamCollector_.GetRendererDeviceInfo(sessionId, deviceInfo);
97
98 AudioStreamType streamType = streamCollector_.GetStreamType(sessionId);
99 if (!CheckStreamOffloadMode(sessionId, streamType)) {
100 return;
101 }
102
103 Trace trace("AudioOffloadStream::OffloadStreamSetCheck:Getting offload stream:" + std::to_string(sessionId));
104 auto CallingUid = IPCSkeleton::GetCallingUid();
105 AUDIO_INFO_LOG("sessionId[%{public}d] CallingUid[%{public}d] StreamType[%{public}d] "
106 "Getting offload stream", sessionId, CallingUid, streamType);
107 std::lock_guard<std::mutex> lock(offloadMutex_);
108
109 if (!offloadSessionID_.has_value()) {
110 offloadSessionID_ = sessionId;
111 audioPolicyManager_.SetOffloadSessionId(sessionId);
112
113 AUDIO_DEBUG_LOG("sessionId[%{public}d] try get offload stream", sessionId);
114 if (MoveToNewPipeInner(sessionId, PIPE_TYPE_OFFLOAD) != SUCCESS) {
115 AUDIO_ERR_LOG("sessionId[%{public}d] CallingUid[%{public}d] StreamType[%{public}d] "
116 "failed to offload stream", sessionId, CallingUid, streamType);
117 offloadSessionID_.reset();
118 audioPolicyManager_.ResetOffloadSessionId();
119 return;
120 }
121 SetOffloadMode();
122 } else {
123 if (sessionId == *(offloadSessionID_)) {
124 AUDIO_DEBUG_LOG("sessionId[%{public}d] is already get offload stream", sessionId);
125 } else {
126 AUDIO_DEBUG_LOG("sessionId[%{public}d] no get offload, current offload sessionId[%{public}d]",
127 sessionId, *(offloadSessionID_));
128 }
129 }
130
131 return;
132 }
133
CheckStreamOffloadMode(int64_t activateSessionId,AudioStreamType streamType)134 bool AudioOffloadStream::CheckStreamOffloadMode(int64_t activateSessionId, AudioStreamType streamType)
135 {
136 if (!GetOffloadAvailableFromXml()) {
137 AUDIO_INFO_LOG("Offload not available, skipped for set");
138 return false;
139 }
140
141 if (!audioActiveDevice_.CheckActiveOutputDeviceSupportOffload()) {
142 AUDIO_PRERELEASE_LOGI("Offload not available on current output device, skipped");
143 return false;
144 }
145
146 if ((streamType != STREAM_MUSIC) && (streamType != STREAM_SPEECH)) {
147 AUDIO_DEBUG_LOG("StreamType not allowed get offload mode, Skipped");
148 return false;
149 }
150
151 AudioPipeType pipeType;
152 streamCollector_.GetPipeType(activateSessionId, pipeType);
153 if (pipeType == PIPE_TYPE_DIRECT_MUSIC) {
154 AUDIO_INFO_LOG("stream is direct, Skipped");
155 return false;
156 }
157
158 int32_t channelCount = streamCollector_.GetChannelCount(activateSessionId);
159 if ((channelCount != AudioChannel::MONO) && (channelCount != AudioChannel::STEREO)) {
160 AUDIO_DEBUG_LOG("ChannelNum not allowed get offload mode, Skipped");
161 return false;
162 }
163
164 int32_t offloadUID = streamCollector_.GetUid(activateSessionId);
165 if (offloadUID == -1) {
166 AUDIO_DEBUG_LOG("offloadUID not valid, Skipped");
167 return false;
168 }
169 if (offloadUID == UID_AUDIO) {
170 AUDIO_DEBUG_LOG("Skip anco_audio out of offload mode");
171 return false;
172 }
173
174 if (CheckSpatializationAndEffectState()) {
175 AUDIO_INFO_LOG("spatialization effect in arm, Skipped");
176 return false;
177 }
178 return true;
179 }
180
ConstructMchAudioModuleInfo(DeviceType deviceType)181 AudioModuleInfo AudioOffloadStream::ConstructMchAudioModuleInfo(DeviceType deviceType)
182 {
183 AudioModuleInfo audioModuleInfo = {};
184 audioModuleInfo.lib = "libmodule-hdi-sink.z.so";
185 audioModuleInfo.format = "s32le"; // 32bit little endian
186 audioModuleInfo.fixedLatency = "1"; // here we need to set latency fixed for a fixed buffer size.
187
188 // used as "sink_name" in hdi_sink.c, hope we could use name to find target sink.
189 audioModuleInfo.name = MCH_PRIMARY_SPEAKER;
190
191 std::stringstream typeValue;
192 typeValue << static_cast<int32_t>(deviceType);
193 audioModuleInfo.deviceType = typeValue.str();
194
195 bool isDefaultAdapterEnable = AudioPolicyConfigManager::GetInstance().GetDefaultAdapterEnable();
196 audioModuleInfo.defaultAdapterEnable = isDefaultAdapterEnable ? "1" : "0";
197 audioModuleInfo.adapterName = "primary";
198 audioModuleInfo.className = "multichannel"; // used in renderer_sink_adapter.c
199 audioModuleInfo.fileName = "mch_dump_file";
200
201 audioModuleInfo.channels = "6";
202 audioModuleInfo.rate = "48000";
203 audioModuleInfo.bufferSize = "7680";
204
205 return audioModuleInfo;
206 }
207
CheckSpatializationAndEffectState()208 bool AudioOffloadStream::CheckSpatializationAndEffectState()
209 {
210 AudioSpatializationState spatialState =
211 AudioSpatializationService::GetAudioSpatializationService().GetSpatializationState();
212 bool effectOffloadFlag = AudioServerProxy::GetInstance().GetEffectOffloadEnabledProxy();
213 return spatialState.spatializationEnabled && !effectOffloadFlag;
214 }
215
LoadMchModule()216 int32_t AudioOffloadStream::LoadMchModule()
217 {
218 AUDIO_INFO_LOG("load multichannel mode");
219 DeviceType deviceType = DEVICE_TYPE_SPEAKER;
220 AudioModuleInfo moduleInfo = ConstructMchAudioModuleInfo(deviceType);
221 audioIOHandleMap_.OpenPortAndInsertIOHandle(moduleInfo.name, moduleInfo);
222 return SUCCESS;
223 }
224
UnloadMchModule()225 int32_t AudioOffloadStream::UnloadMchModule()
226 {
227 AUDIO_INFO_LOG("unload multichannel module");
228 return audioIOHandleMap_.ClosePortAndEraseIOHandle(MCH_PRIMARY_SPEAKER);
229 }
230
MoveToNewPipeInner(uint32_t sessionId,AudioPipeType pipeType)231 int32_t AudioOffloadStream::MoveToNewPipeInner(uint32_t sessionId, AudioPipeType pipeType)
232 {
233 AudioPipeType oldPipeType;
234 streamCollector_.GetPipeType(sessionId, oldPipeType);
235 Trace tracePipe("AudioOffloadStream::MoveToNewPipeInner:sessionId:" + std::to_string(sessionId) +
236 " from " + std::to_string(oldPipeType) + " to " + std::to_string(pipeType));
237 if (oldPipeType == pipeType) {
238 AUDIO_ERR_LOG("the same type [%{public}d],no need to move", pipeType);
239 return SUCCESS;
240 }
241 Trace trace("AudioOffloadStream::MoveToNewPipeInner");
242 AUDIO_INFO_LOG("start move stream %{public}d from %{public}d into new pipe %{public}d", sessionId,
243 oldPipeType, pipeType);
244 int32_t ret = SwitchToNewPipe(sessionId, pipeType);
245
246 return ret;
247 }
248
SwitchToNewPipe(const uint32_t sessionId,const AudioPipeType pipeType)249 int32_t AudioOffloadStream::SwitchToNewPipe(const uint32_t sessionId, const AudioPipeType pipeType)
250 {
251 int32_t ret = ERROR;
252 std::string portName = PORT_NONE;
253 AudioStreamType streamType = streamCollector_.GetStreamType(sessionId);
254 DeviceType deviceType = audioActiveDevice_.GetCurrentOutputDeviceType();
255 switch (pipeType) {
256 case PIPE_TYPE_OFFLOAD: {
257 if (!CheckStreamOffloadMode(sessionId, streamType)) {
258 return ERROR;
259 }
260 if (LoadOffloadModule() != SUCCESS) {
261 return ERROR;
262 }
263 portName = AudioPolicyUtils::GetInstance().GetSinkPortName(deviceType, pipeType);
264 audioIOHandleMap_.MuteSinkPort(portName, SELECT_PIPE_TYPE_OFFLOAD_MUTE_US, true, false);
265 ret = MoveToOutputDevice(sessionId, portName);
266 break;
267 }
268 case PIPE_TYPE_MULTICHANNEL: {
269 if (!CheckStreamMultichannelMode(sessionId)) {
270 return ERROR;
271 }
272 if (audioIOHandleMap_.CheckIOHandleExist(MCH_PRIMARY_SPEAKER) == false) {
273 // load moudle and move into new sink
274 LoadMchModule();
275 }
276 portName = AudioPolicyUtils::GetInstance().GetSinkPortName(deviceType, pipeType);
277 ret = MoveToOutputDevice(sessionId, portName);
278 break;
279 }
280 case PIPE_TYPE_NORMAL_OUT: {
281 portName = AudioPolicyUtils::GetInstance().GetSinkPortName(deviceType, pipeType);
282 ret = MoveToOutputDevice(sessionId, portName);
283 break;
284 }
285 default:
286 AUDIO_WARNING_LOG("not supported for pipe type %{public}d", pipeType);
287 break;
288 }
289 if (ret == SUCCESS) {
290 streamCollector_.UpdateRendererPipeInfo(sessionId, pipeType);
291 }
292 return ret;
293 }
294
ResetOffloadMode(int32_t sessionId)295 void AudioOffloadStream::ResetOffloadMode(int32_t sessionId)
296 {
297 }
298
OffloadStreamReleaseCheck(uint32_t sessionId)299 void AudioOffloadStream::OffloadStreamReleaseCheck(uint32_t sessionId)
300 {
301 if (!GetOffloadAvailableFromXml()) {
302 AUDIO_INFO_LOG("Offload not available, skipped for release");
303 return;
304 }
305
306 std::lock_guard<std::mutex> lock(offloadMutex_);
307
308 if (((*offloadSessionID_) == sessionId) && offloadSessionID_.has_value()) {
309 AUDIO_DEBUG_LOG("Doing unset offload mode!");
310 AudioServerProxy::GetInstance().UnsetOffloadModeProxy(*offloadSessionID_);
311 AudioPipeType normalPipe = PIPE_TYPE_NORMAL_OUT;
312 MoveToNewPipe(sessionId, normalPipe);
313 streamCollector_.UpdateRendererPipeInfo(sessionId, normalPipe);
314 DynamicUnloadOffloadModule();
315 offloadSessionID_.reset();
316 audioPolicyManager_.ResetOffloadSessionId();
317 AUDIO_DEBUG_LOG("sessionId[%{public}d] release offload stream", sessionId);
318 } else {
319 if (offloadSessionID_.has_value()) {
320 AUDIO_DEBUG_LOG("sessionId[%{public}d] stopping stream not get offload, current offload [%{public}d]",
321 sessionId, *offloadSessionID_);
322 } else {
323 AUDIO_DEBUG_LOG("sessionId[%{public}d] stopping stream not get offload, current offload stream is None",
324 sessionId);
325 }
326 }
327 return;
328 }
329
MoveToNewPipe(uint32_t sessionId,AudioPipeType pipeType)330 int32_t AudioOffloadStream::MoveToNewPipe(uint32_t sessionId, AudioPipeType pipeType)
331 {
332 // Check if the stream exists
333 int32_t defaultUid = -1;
334 if (defaultUid == streamCollector_.GetUid(sessionId)) {
335 AUDIO_ERR_LOG("The audio stream information [%{public}d] is illegal", sessionId);
336 return ERROR;
337 }
338 // move the stream to new pipe
339 return MoveToNewPipeInner(sessionId, pipeType);
340 }
341
ConstructOffloadAudioModuleInfo(DeviceType deviceType)342 AudioModuleInfo AudioOffloadStream::ConstructOffloadAudioModuleInfo(DeviceType deviceType)
343 {
344 AudioModuleInfo audioModuleInfo = {};
345 audioModuleInfo.lib = "libmodule-hdi-sink.z.so";
346 audioModuleInfo.format = "s32le"; // 32bit little endian
347 audioModuleInfo.fixedLatency = "1"; // here we need to set latency fixed for a fixed buffer size.
348
349 // used as "sink_name" in hdi_sink.c, hope we could use name to find target sink.
350 audioModuleInfo.name = OFFLOAD_PRIMARY_SPEAKER;
351
352 std::stringstream typeValue;
353 typeValue << static_cast<int32_t>(deviceType);
354 audioModuleInfo.deviceType = typeValue.str();
355
356 audioModuleInfo.adapterName = "primary";
357 audioModuleInfo.className = "offload"; // used in renderer_sink_adapter.c
358 audioModuleInfo.fileName = "offload_dump_file";
359 audioModuleInfo.offloadEnable = "1";
360
361 audioModuleInfo.channels = "2";
362 audioModuleInfo.rate = "48000";
363 audioModuleInfo.bufferSize = "7680";
364
365 return audioModuleInfo;
366 }
367
LoadOffloadModule()368 int32_t AudioOffloadStream::LoadOffloadModule()
369 {
370 AUDIO_INFO_LOG("load offload mode");
371 std::unique_lock<std::mutex> lock(offloadCloseMutex_);
372 isOffloadOpened_.store(true);
373 offloadCloseCondition_.notify_all();
374 {
375 std::lock_guard<std::mutex> lk(offloadOpenMutex_);
376 if (audioIOHandleMap_.CheckIOHandleExist(OFFLOAD_PRIMARY_SPEAKER)) {
377 AUDIO_INFO_LOG("offload is open");
378 return SUCCESS;
379 }
380
381 DeviceType deviceType = DEVICE_TYPE_SPEAKER;
382 AudioModuleInfo moduleInfo = ConstructOffloadAudioModuleInfo(deviceType);
383 return audioIOHandleMap_.OpenPortAndInsertIOHandle(moduleInfo.name, moduleInfo);
384 }
385 return SUCCESS;
386 }
387
UnloadOffloadModule()388 int32_t AudioOffloadStream::UnloadOffloadModule()
389 {
390 AUDIO_INFO_LOG("unload offload module");
391 std::unique_lock<std::mutex> lock(offloadCloseMutex_);
392 // Try to wait 3 seconds before unloading the module, because the audio driver takes some time to process
393 // the shutdown process..
394 offloadCloseCondition_.wait_for(lock, std::chrono::seconds(WAIT_OFFLOAD_CLOSE_TIME_S),
395 [this] () { return isOffloadOpened_.load(); });
396 {
397 std::lock_guard<std::mutex> lk(offloadOpenMutex_);
398 if (isOffloadOpened_.load()) {
399 AUDIO_INFO_LOG("offload restart");
400 return ERROR;
401 }
402 audioIOHandleMap_.ClosePortAndEraseIOHandle(OFFLOAD_PRIMARY_SPEAKER);
403 }
404 return SUCCESS;
405 }
406
407
DynamicUnloadOffloadModule()408 int32_t AudioOffloadStream::DynamicUnloadOffloadModule()
409 {
410 if (isOffloadOpened_.load()) {
411 isOffloadOpened_.store(false);
412 auto unloadFirOffloadThrd = [this] { this->UnloadOffloadModule(); };
413 std::thread unloadOffloadThrd(unloadFirOffloadThrd);
414 unloadOffloadThrd.detach();
415 }
416 return SUCCESS;
417 }
418
RemoteOffloadStreamRelease(uint32_t sessionId)419 void AudioOffloadStream::RemoteOffloadStreamRelease(uint32_t sessionId)
420 {
421 std::lock_guard<std::mutex> lock(offloadMutex_);
422 if (offloadSessionID_.has_value() && ((*offloadSessionID_) == sessionId)) {
423 AUDIO_DEBUG_LOG("Doing unset offload mode!");
424 AudioServerProxy::GetInstance().UnsetOffloadModeProxy(*offloadSessionID_);
425 AudioPipeType normalPipe = PIPE_TYPE_UNKNOWN;
426 MoveToNewPipe(sessionId, normalPipe);
427 streamCollector_.UpdateRendererPipeInfo(sessionId, normalPipe);
428 DynamicUnloadOffloadModule();
429 offloadSessionID_.reset();
430 audioPolicyManager_.ResetOffloadSessionId();
431 AUDIO_DEBUG_LOG("sessionId[%{public}d] release offload stream", sessionId);
432 }
433 }
434
MoveToOutputDevice(uint32_t sessionId,std::string portName)435 int32_t AudioOffloadStream::MoveToOutputDevice(uint32_t sessionId, std::string portName)
436 {
437 std::vector<SinkInput> sinkInputs;
438 audioPolicyManager_.GetAllSinkInputs(sinkInputs);
439 std::vector<SinkInput> sinkInputIds = FilterSinkInputs(sessionId, sinkInputs);
440
441 if (portName == BLUETOOTH_SPEAKER) {
442 std::string activePort = BLUETOOTH_SPEAKER;
443 audioPolicyManager_.SuspendAudioDevice(activePort, false);
444 }
445 AUDIO_INFO_LOG("move for session [%{public}d], portName %{public}s", sessionId, portName.c_str());
446 // start move.
447 uint32_t sinkId = -1; // invalid sink id, use sink name instead.
448 for (size_t i = 0; i < sinkInputIds.size(); i++) {
449 int32_t ret = audioPolicyManager_.MoveSinkInputByIndexOrName(sinkInputIds[i].paStreamId, sinkId, portName);
450 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR,
451 "move [%{public}d] to local failed", sinkInputIds[i].streamId);
452 audioRouteMap_.AddRouteMapInfo(sinkInputIds[i].uid, LOCAL_NETWORK_ID, sinkInputIds[i].pid);
453 }
454 return SUCCESS;
455 }
456
CheckStreamMultichannelMode(const int64_t activateSessionId)457 bool AudioOffloadStream::CheckStreamMultichannelMode(const int64_t activateSessionId)
458 {
459 if (audioActiveDevice_.GetCurrentOutputDeviceNetworkId() != LOCAL_NETWORK_ID ||
460 audioActiveDevice_.GetCurrentOutputDeviceType() == DEVICE_TYPE_REMOTE_CAST) {
461 return false;
462 }
463
464 // Multi-channel mode only when the number of channels is greater than 2.
465 int32_t channelCount = streamCollector_.GetChannelCount(activateSessionId);
466 if (channelCount < AudioChannel::CHANNEL_3) {
467 AUDIO_DEBUG_LOG("ChannelNum not allowed get multichannel mode, Skipped");
468 return false;
469 }
470
471 // The multi-channel algorithm needs to be supported in the DSP
472 return AudioServerProxy::GetInstance().GetEffectOffloadEnabledProxy();
473 }
474
FilterSinkInputs(int32_t sessionId,std::vector<SinkInput> sinkInputs)475 std::vector<SinkInput> AudioOffloadStream::FilterSinkInputs(int32_t sessionId, std::vector<SinkInput> sinkInputs)
476 {
477 // find sink-input id with audioRendererFilter
478 std::vector<SinkInput> targetSinkInputs = {};
479
480 for (size_t i = 0; i < sinkInputs.size(); i++) {
481 CHECK_AND_CONTINUE_LOG(sinkInputs[i].uid != dAudioClientUid,
482 "Find sink-input with daudio[%{public}d]", sinkInputs[i].pid);
483 CHECK_AND_CONTINUE_LOG(sinkInputs[i].streamType != STREAM_DEFAULT,
484 "Sink-input[%{public}zu] of effect sink, don't move", i);
485 AUDIO_DEBUG_LOG("sinkinput[%{public}zu]:%{public}s", i, PrintSinkInput(sinkInputs[i]).c_str());
486 if (sessionId == sinkInputs[i].streamId) {
487 targetSinkInputs.push_back(sinkInputs[i]);
488 }
489 }
490 return targetSinkInputs;
491 }
492
ResetOffloadModeOnSpatializationChanged(std::vector<int32_t> & allSessions)493 void AudioOffloadStream::ResetOffloadModeOnSpatializationChanged(std::vector<int32_t> &allSessions)
494 {
495 AudioSpatializationState spatialState =
496 AudioSpatializationService::GetAudioSpatializationService().GetSpatializationState();
497 bool effectOffloadFlag = AudioServerProxy::GetInstance().GetEffectOffloadEnabledProxy();
498 AUDIO_INFO_LOG("spatialization: %{public}d, headTracking: %{public}d, effectOffloadFlag: %{public}d",
499 spatialState.spatializationEnabled, spatialState.headTrackingEnabled, effectOffloadFlag);
500 if (spatialState.spatializationEnabled) {
501 if (effectOffloadFlag) {
502 for (auto it = allSessions.begin(); it != allSessions.end(); it++) {
503 OffloadStreamSetCheck(*it);
504 }
505 } else {
506 OffloadStreamReleaseCheck(*offloadSessionID_);
507 }
508 }
509 }
510
ResetOffloadStatus(uint32_t sessionId)511 void AudioOffloadStream::ResetOffloadStatus(uint32_t sessionId)
512 {
513 AUDIO_INFO_LOG("Reset offload state for session: %{public}u", sessionId);
514 if (offloadSessionID_.has_value() && ((*offloadSessionID_) == sessionId)) {
515 AUDIO_INFO_LOG("Current offload session: %{public}u", (*offloadSessionID_));
516 std::lock_guard<std::mutex> lock(offloadMutex_);
517 AudioServerProxy::GetInstance().UnsetOffloadModeProxy(sessionId);
518 AudioPipeType normalPipe = PIPE_TYPE_NORMAL_OUT;
519 streamCollector_.UpdateRendererPipeInfo(sessionId, normalPipe);
520 offloadSessionID_.reset();
521 audioPolicyManager_.ResetOffloadSessionId();
522 }
523 }
524
SetOffloadStatus(uint32_t sessionId)525 void AudioOffloadStream::SetOffloadStatus(uint32_t sessionId)
526 {
527 AudioStreamType streamType = streamCollector_.GetStreamType(sessionId);
528 auto callingUid = IPCSkeleton::GetCallingUid();
529 AUDIO_INFO_LOG("sessionId[%{public}d] callingUid[%{public}d] StreamType[%{public}d] "
530 "Getting offload stream", sessionId, callingUid, streamType);
531 std::lock_guard<std::mutex> lock(offloadMutex_);
532
533 if (!offloadSessionID_.has_value()) {
534 offloadSessionID_ = sessionId;
535 audioPolicyManager_.SetOffloadSessionId(sessionId);
536 AUDIO_DEBUG_LOG("sessionId[%{public}d] try get offload stream", sessionId);
537 SetOffloadMode();
538 AudioPipeType offloadPipe = PIPE_TYPE_OFFLOAD;
539 streamCollector_.UpdateRendererPipeInfo(sessionId, offloadPipe);
540 } else {
541 if (sessionId == *(offloadSessionID_)) {
542 AUDIO_DEBUG_LOG("sessionId[%{public}d] is already get offload stream", sessionId);
543 } else {
544 AUDIO_DEBUG_LOG("sessionId[%{public}d] no get offload, current offload sessionId[%{public}d]",
545 sessionId, *(offloadSessionID_));
546 }
547 }
548 }
549 }
550 }
551