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 "AudioRecoveryDevice"
17 #endif
18
19 #include "audio_recovery_device.h"
20 #include "parameter.h"
21 #include "parameters.h"
22 #include "audio_policy_log.h"
23
24 #include "audio_server_proxy.h"
25 #include "audio_policy_utils.h"
26
27 namespace OHOS {
28 namespace AudioStandard {
29
30 namespace {
31 constexpr int32_t RECOVERY_ATTEMPT_LIMIT = 5;
32 constexpr uint32_t INITIAL_STREAM_RESTORATION_WAIT_US = 1000000;
33 constexpr uint32_t RETRY_INTERVAL_US = 300000;
34 constexpr int32_t EXCLUDED = 0;
35 constexpr int32_t UNEXCLUDED = 1;
36 } // namespace
37
GetEncryptAddr(const std::string & addr)38 static std::string GetEncryptAddr(const std::string &addr)
39 {
40 const int32_t START_POS = 6;
41 const int32_t END_POS = 13;
42 const int32_t ADDRESS_STR_LEN = 17;
43 if (addr.empty() || addr.length() != ADDRESS_STR_LEN) {
44 return std::string("");
45 }
46 std::string tmp = "**:**:**:**:**:**";
47 std::string out = addr;
48 for (int i = START_POS; i <= END_POS; i++) {
49 out[i] = tmp[i];
50 }
51 return out;
52 }
53
Init(std::shared_ptr<AudioA2dpOffloadManager> audioA2dpOffloadManager)54 void AudioRecoveryDevice::Init(std::shared_ptr<AudioA2dpOffloadManager> audioA2dpOffloadManager)
55 {
56 audioA2dpOffloadManager_ = audioA2dpOffloadManager;
57 }
58
DeInit()59 void AudioRecoveryDevice::DeInit()
60 {
61 audioA2dpOffloadManager_ = nullptr;
62 }
63
RecoveryPreferredDevices()64 void AudioRecoveryDevice::RecoveryPreferredDevices()
65 {
66 AUDIO_DEBUG_LOG("Start recovery preferred devices.");
67 int32_t tryCounter = RECOVERY_ATTEMPT_LIMIT;
68 // Waiting for 1000000 μs. Ensure that the playback/recording stream is restored first
69 uint32_t firstSleepTime = INITIAL_STREAM_RESTORATION_WAIT_US;
70 // Retry interval
71 uint32_t sleepTime = RETRY_INTERVAL_US;
72 int32_t result = -1;
73 std::map<Media::MediaMonitor::PreferredType,
74 std::shared_ptr<Media::MediaMonitor::MonitorDeviceInfo>> preferredDevices;
75 usleep(firstSleepTime);
76 while (result != SUCCESS && tryCounter > 0) {
77 tryCounter--;
78 Media::MediaMonitor::MediaMonitorManager::GetInstance().GetAudioRouteMsg(preferredDevices);
79 if (preferredDevices.size() == 0) {
80 continue;
81 }
82 for (auto iter = preferredDevices.begin(); iter != preferredDevices.end(); ++iter) {
83 result = HandleRecoveryPreferredDevices(static_cast<int32_t>(iter->first), iter->second->deviceType_,
84 iter->second->usageOrSourceType_);
85 if (result != SUCCESS) {
86 AUDIO_ERR_LOG("Handle recovery preferred devices failed"
87 ", deviceType:%{public}d, usageOrSourceType:%{public}d, tryCounter:%{public}d",
88 iter->second->deviceType_, iter->second->usageOrSourceType_, tryCounter);
89 }
90 }
91 if (result != SUCCESS) {
92 usleep(sleepTime);
93 }
94 }
95 }
96
HandleRecoveryPreferredDevices(int32_t preferredType,int32_t deviceType,int32_t usageOrSourceType)97 int32_t AudioRecoveryDevice::HandleRecoveryPreferredDevices(int32_t preferredType, int32_t deviceType,
98 int32_t usageOrSourceType)
99 {
100 int32_t result = -1;
101 auto it = audioConnectedDevice_.GetConnectedDeviceByType(deviceType);
102 if (it != nullptr) {
103 std::vector<std::shared_ptr<AudioDeviceDescriptor>> deviceDescriptorVector;
104 deviceDescriptorVector.push_back(it);
105 if (preferredType == Media::MediaMonitor::MEDIA_RENDER ||
106 preferredType == Media::MediaMonitor::CALL_RENDER ||
107 preferredType == Media::MediaMonitor::RING_RENDER ||
108 preferredType == Media::MediaMonitor::TONE_RENDER) {
109 sptr<AudioRendererFilter> audioRendererFilter = new(std::nothrow) AudioRendererFilter();
110 audioRendererFilter->uid = -1;
111 audioRendererFilter->rendererInfo.streamUsage =
112 static_cast<StreamUsage>(usageOrSourceType);
113 result = SelectOutputDevice(audioRendererFilter, deviceDescriptorVector);
114 } else if (preferredType == Media::MediaMonitor::CALL_CAPTURE ||
115 preferredType == Media::MediaMonitor::RECORD_CAPTURE) {
116 sptr<AudioCapturerFilter> audioCapturerFilter = new(std::nothrow) AudioCapturerFilter();
117 audioCapturerFilter->uid = -1;
118 audioCapturerFilter->capturerInfo.sourceType =
119 static_cast<SourceType>(usageOrSourceType);
120 result = SelectInputDevice(audioCapturerFilter, deviceDescriptorVector);
121 }
122 }
123 return result;
124 }
125
RecoverExcludedOutputDevices()126 void AudioRecoveryDevice::RecoverExcludedOutputDevices()
127 {
128 AUDIO_INFO_LOG("Start recover excluded output devices.");
129 int32_t tryCounter = RECOVERY_ATTEMPT_LIMIT;
130 // Waiting for 1000000 μs. Ensure that the playback/recording stream is restored first
131 uint32_t firstSleepTime = INITIAL_STREAM_RESTORATION_WAIT_US;
132 // Retry interval
133 uint32_t sleepTime = RETRY_INTERVAL_US;
134 int32_t result = -1;
135 map<Media::MediaMonitor::AudioDeviceUsage,
136 vector<shared_ptr<Media::MediaMonitor::MonitorDeviceInfo>>> excludedDevicesMap;
137 usleep(firstSleepTime);
138 while (result != SUCCESS && tryCounter > 0) {
139 tryCounter--;
140 Media::MediaMonitor::MediaMonitorManager::GetInstance().GetAudioExcludedDevicesMsg(excludedDevicesMap);
141 for (auto iter = excludedDevicesMap.begin(); iter != excludedDevicesMap.end(); ++iter) {
142 result = HandleExcludedOutputDevicesRecovery(static_cast<AudioDeviceUsage>(iter->first), iter->second);
143 CHECK_AND_CONTINUE_LOG(result == SUCCESS, "Handle usage[%{public}d] excluded devices recovery failed",
144 iter->first);
145 }
146 if (result != SUCCESS) {
147 usleep(sleepTime);
148 }
149 }
150 }
151
HandleExcludedOutputDevicesRecovery(AudioDeviceUsage audioDevUsage,std::vector<std::shared_ptr<Media::MediaMonitor::MonitorDeviceInfo>> & excludedDevices)152 int32_t AudioRecoveryDevice::HandleExcludedOutputDevicesRecovery(AudioDeviceUsage audioDevUsage,
153 std::vector<std::shared_ptr<Media::MediaMonitor::MonitorDeviceInfo>> &excludedDevices)
154 {
155 vector<shared_ptr<AudioDeviceDescriptor>> excludedOutputDevices;
156 for (auto &device : excludedDevices) {
157 auto it = audioConnectedDevice_.GetConnectedDeviceByType(device->networkId_,
158 static_cast<DeviceType>(device->deviceType_), device->address_);
159 if (it != nullptr) {
160 excludedOutputDevices.push_back(it);
161 }
162 }
163 if (!excludedOutputDevices.empty()) {
164 return ExcludeOutputDevices(audioDevUsage, excludedOutputDevices);
165 }
166 return ERROR;
167 }
168
SelectOutputDevice(sptr<AudioRendererFilter> audioRendererFilter,std::vector<std::shared_ptr<AudioDeviceDescriptor>> selectedDesc)169 int32_t AudioRecoveryDevice::SelectOutputDevice(sptr<AudioRendererFilter> audioRendererFilter,
170 std::vector<std::shared_ptr<AudioDeviceDescriptor>> selectedDesc)
171 {
172 AUDIO_WARNING_LOG("uid[%{public}d] type[%{public}d] mac[%{public}s] streamUsage[%{public}d] callerUid[%{public}d]",
173 audioRendererFilter->uid, selectedDesc[0]->deviceType_, GetEncryptAddr(selectedDesc[0]->macAddress_).c_str(),
174 audioRendererFilter->rendererInfo.streamUsage, IPCSkeleton::GetCallingUid());
175
176 CHECK_AND_RETURN_RET_LOG((selectedDesc[0]->deviceRole_ == DeviceRole::OUTPUT_DEVICE) &&
177 (selectedDesc.size() == 1), ERR_INVALID_OPERATION, "DeviceCheck no success");
178
179 int32_t res = SUCCESS;
180 StreamUsage strUsage = audioRendererFilter->rendererInfo.streamUsage;
181 auto audioDevUsage = AudioPolicyUtils::GetInstance().GetAudioDeviceUsageByStreamUsage(strUsage);
182 if (audioStateManager_.IsExcludedDevice(audioDevUsage, selectedDesc[0])) {
183 res = UnexcludeOutputDevicesInner(audioDevUsage, selectedDesc);
184 CHECK_AND_RETURN_RET_LOG(res == SUCCESS, res, "UnexcludeOutputDevicesInner fail");
185 }
186
187 if (audioRendererFilter->uid != -1) { return SelectOutputDeviceByFilterInner(audioRendererFilter, selectedDesc); }
188 if (audioRendererFilter->rendererInfo.rendererFlags == STREAM_FLAG_FAST) {
189 return SelectOutputDeviceForFastInner(audioRendererFilter, selectedDesc);
190 }
191
192 bool isVirtualDevice = false;
193 if (selectedDesc[0]->deviceType_ == DEVICE_TYPE_BLUETOOTH_A2DP ||
194 selectedDesc[0]->deviceType_ == DEVICE_TYPE_BLUETOOTH_SCO) {
195 selectedDesc[0]->isEnable_ = true;
196 audioDeviceManager_.UpdateDevicesListInfo(selectedDesc[0], ENABLE_UPDATE);
197 isVirtualDevice = audioDeviceManager_.IsVirtualConnectedDevice(selectedDesc[0]);
198 if (isVirtualDevice == true) {
199 selectedDesc[0]->connectState_ = VIRTUAL_CONNECTED;
200 }
201 }
202 if (selectedDesc[0]->deviceType_ == DEVICE_TYPE_BLUETOOTH_SCO) {
203 AudioPolicyUtils::GetInstance().ClearScoDeviceSuspendState(selectedDesc[0]->macAddress_);
204 }
205 SetRenderDeviceForUsage(strUsage, selectedDesc[0]);
206 CHECK_AND_RETURN_RET_LOG(res == SUCCESS, res, "SetRenderDeviceForUsage fail");
207
208 // If the selected device is virtual device, connect it.
209 if (isVirtualDevice) {
210 int32_t ret = ConnectVirtualDevice(selectedDesc[0]);
211 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Connect device [%{public}s] failed",
212 GetEncryptStr(selectedDesc[0]->macAddress_).c_str());
213 return SUCCESS;
214 }
215
216 audioActiveDevice_.NotifyUserSelectionEventToBt(selectedDesc[0]);
217 HandleFetchDeviceChange(AudioStreamDeviceChangeReason::OVERRODE, "SelectOutputDevice");
218 audioDeviceCommon_.OnPreferredOutputDeviceUpdated(audioActiveDevice_.GetCurrentOutputDevice());
219 WriteSelectOutputSysEvents(selectedDesc, strUsage);
220 return SUCCESS;
221 }
222
HandleFetchDeviceChange(const AudioStreamDeviceChangeReason & reason,const std::string & caller)223 void AudioRecoveryDevice::HandleFetchDeviceChange(const AudioStreamDeviceChangeReason &reason,
224 const std::string &caller)
225 {
226 audioDeviceCommon_.FetchDevice(true, reason);
227 audioDeviceCommon_.FetchDevice(false);
228 auto currentInputDevice = audioActiveDevice_.GetCurrentInputDevice();
229 auto currentOutputDevice = audioActiveDevice_.GetCurrentOutputDevice();
230 audioCapturerSession_.ReloadSourceForDeviceChange(
231 currentInputDevice,
232 currentOutputDevice, caller);
233 if ((currentOutputDevice.deviceType_ != DEVICE_TYPE_BLUETOOTH_A2DP) ||
234 (currentOutputDevice.networkId_ != LOCAL_NETWORK_ID)) {
235 audioA2dpOffloadManager_->UpdateOffloadWhenActiveDeviceSwitchFromA2dp();
236 } else {
237 audioA2dpOffloadManager_->UpdateA2dpOffloadFlagForAllStream(currentOutputDevice.deviceType_);
238 }
239 }
240
SelectOutputDeviceForFastInner(sptr<AudioRendererFilter> audioRendererFilter,std::vector<std::shared_ptr<AudioDeviceDescriptor>> selectedDesc)241 int32_t AudioRecoveryDevice::SelectOutputDeviceForFastInner(sptr<AudioRendererFilter> audioRendererFilter,
242 std::vector<std::shared_ptr<AudioDeviceDescriptor>> selectedDesc)
243 {
244 int32_t res = SetRenderDeviceForUsage(audioRendererFilter->rendererInfo.streamUsage, selectedDesc[0]);
245 CHECK_AND_RETURN_RET_LOG(res == SUCCESS, res, "SetRenderDeviceForUsage fail");
246 SetRenderDeviceForUsage(audioRendererFilter->rendererInfo.streamUsage, selectedDesc[0]);
247 res = SelectFastOutputDevice(audioRendererFilter, selectedDesc[0]);
248 CHECK_AND_RETURN_RET_LOG(res == SUCCESS, res,
249 "AddFastRouteMapInfo failed! fastRouteMap is too large!");
250 audioDeviceCommon_.FetchDevice(true, AudioStreamDeviceChangeReason::OVERRODE);
251 return true;
252 }
253
SetRenderDeviceForUsage(StreamUsage streamUsage,std::shared_ptr<AudioDeviceDescriptor> desc)254 int32_t AudioRecoveryDevice::SetRenderDeviceForUsage(StreamUsage streamUsage,
255 std::shared_ptr<AudioDeviceDescriptor> desc)
256 {
257 // get deviceUsage and preferredType
258 auto deviceUsage = AudioPolicyUtils::GetInstance().GetAudioDeviceUsageByStreamUsage(streamUsage);
259 auto preferredType = AudioPolicyUtils::GetInstance().GetPreferredTypeByStreamUsage(streamUsage);
260 auto tempId = desc->deviceId_;
261
262 // find device
263 auto devices = AudioPolicyUtils::GetInstance().GetAvailableDevicesInner(deviceUsage);
264 auto itr = std::find_if(devices.begin(), devices.end(), [&desc](const auto &device) {
265 return (desc->deviceType_ == device->deviceType_) &&
266 (desc->macAddress_ == device->macAddress_) &&
267 (desc->networkId_ == device->networkId_) &&
268 (!IsUsb(desc->deviceType_) || desc->deviceRole_ == device->deviceRole_);
269 });
270 CHECK_AND_RETURN_RET_LOG(itr != devices.end(), ERR_INVALID_OPERATION,
271 "device not available type:%{public}d macAddress:%{public}s id:%{public}d networkId:%{public}s",
272 desc->deviceType_, GetEncryptAddr(desc->macAddress_).c_str(),
273 tempId, GetEncryptStr(desc->networkId_).c_str());
274 // set preferred device
275 std::shared_ptr<AudioDeviceDescriptor> descriptor = std::make_shared<AudioDeviceDescriptor>(**itr);
276 CHECK_AND_RETURN_RET_LOG(descriptor != nullptr, ERR_INVALID_OPERATION, "Create device descriptor failed");
277
278 auto callerUid = IPCSkeleton::GetCallingUid();
279 if (preferredType == AUDIO_CALL_RENDER) {
280 AudioPolicyUtils::GetInstance().SetPreferredDevice(preferredType, descriptor, callerUid, "SelectOutputDevice");
281 } else {
282 AudioPolicyUtils::GetInstance().SetPreferredDevice(preferredType, descriptor);
283 }
284 return SUCCESS;
285 }
286
ConnectVirtualDevice(std::shared_ptr<AudioDeviceDescriptor> & selectedDesc)287 int32_t AudioRecoveryDevice::ConnectVirtualDevice(std::shared_ptr<AudioDeviceDescriptor> &selectedDesc)
288 {
289 int32_t ret = Bluetooth::AudioA2dpManager::Connect(selectedDesc->macAddress_);
290 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "A2dp connect failed");
291 ret = Bluetooth::AudioHfpManager::Connect(selectedDesc->macAddress_);
292 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Hfp connect failed");
293 AUDIO_INFO_LOG("Connect virtual device[%{public}s]", GetEncryptAddr(selectedDesc->macAddress_).c_str());
294 return SUCCESS;
295 }
296
WriteSelectOutputSysEvents(const std::vector<std::shared_ptr<AudioDeviceDescriptor>> & selectedDesc,StreamUsage strUsage)297 void AudioRecoveryDevice::WriteSelectOutputSysEvents(
298 const std::vector<std::shared_ptr<AudioDeviceDescriptor>> &selectedDesc,
299 StreamUsage strUsage)
300 {
301 std::shared_ptr<Media::MediaMonitor::EventBean> bean = std::make_shared<Media::MediaMonitor::EventBean>(
302 Media::MediaMonitor::AUDIO, Media::MediaMonitor::SET_FORCE_USE_AUDIO_DEVICE,
303 Media::MediaMonitor::BEHAVIOR_EVENT);
304 AudioDeviceDescriptor curOutputDeviceDesc = audioActiveDevice_.GetCurrentOutputDevice();
305 bean->Add("CLIENT_UID", static_cast<int32_t>(IPCSkeleton::GetCallingUid()));
306 bean->Add("DEVICE_TYPE", curOutputDeviceDesc.deviceType_);
307 bean->Add("STREAM_TYPE", strUsage);
308 bean->Add("BT_TYPE", curOutputDeviceDesc.deviceCategory_);
309 bean->Add("DEVICE_NAME", curOutputDeviceDesc.deviceName_);
310 bean->Add("ADDRESS", curOutputDeviceDesc.macAddress_);
311 bean->Add("IS_PLAYBACK", 1);
312 Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
313 }
314
SelectFastOutputDevice(sptr<AudioRendererFilter> audioRendererFilter,std::shared_ptr<AudioDeviceDescriptor> deviceDescriptor)315 int32_t AudioRecoveryDevice::SelectFastOutputDevice(sptr<AudioRendererFilter> audioRendererFilter,
316 std::shared_ptr<AudioDeviceDescriptor> deviceDescriptor)
317 {
318 AUDIO_INFO_LOG("Start for uid[%{public}d] device[%{public}s]", audioRendererFilter->uid,
319 GetEncryptStr(deviceDescriptor->networkId_).c_str());
320 // note: check if stream is already running
321 // if is running, call moveProcessToEndpoint.
322
323 // otherwises, keep router info in the map
324 int32_t res = audioRouteMap_.AddFastRouteMapInfo(audioRendererFilter->uid, deviceDescriptor->networkId_,
325 OUTPUT_DEVICE);
326 return res;
327 }
328
SelectOutputDeviceByFilterInner(sptr<AudioRendererFilter> audioRendererFilter,std::vector<std::shared_ptr<AudioDeviceDescriptor>> selectedDesc)329 int32_t AudioRecoveryDevice::SelectOutputDeviceByFilterInner(sptr<AudioRendererFilter> audioRendererFilter,
330 std::vector<std::shared_ptr<AudioDeviceDescriptor>> selectedDesc)
331 {
332 if (selectedDesc[0]->deviceType_ == DEVICE_TYPE_BLUETOOTH_A2DP ||
333 selectedDesc[0]->deviceType_ == DEVICE_TYPE_BLUETOOTH_SCO) {
334 selectedDesc[0]->isEnable_ = true;
335 audioDeviceManager_.UpdateDevicesListInfo(selectedDesc[0], ENABLE_UPDATE);
336 bool isVirtualDevice = audioDeviceManager_.IsVirtualConnectedDevice(selectedDesc[0]);
337 if (isVirtualDevice == true) {
338 selectedDesc[0]->connectState_ = VIRTUAL_CONNECTED;
339 }
340 }
341 audioAffinityManager_.AddSelectRendererDevice(audioRendererFilter->uid, selectedDesc[0]);
342 std::vector<std::shared_ptr<AudioRendererChangeInfo>> rendererChangeInfos;
343 streamCollector_.GetCurrentRendererChangeInfos(rendererChangeInfos);
344 for (auto &changeInfo : rendererChangeInfos) {
345 if (changeInfo->clientUID == audioRendererFilter->uid && changeInfo->sessionId != 0) {
346 RestoreInfo restoreInfo;
347 restoreInfo.restoreReason = STREAM_SPLIT;
348 AudioServerProxy::GetInstance().RestoreSessionProxy(changeInfo->sessionId, restoreInfo);
349 }
350 }
351 return SUCCESS;
352 }
353
SelectInputDevice(sptr<AudioCapturerFilter> audioCapturerFilter,std::vector<std::shared_ptr<AudioDeviceDescriptor>> selectedDesc)354 int32_t AudioRecoveryDevice::SelectInputDevice(sptr<AudioCapturerFilter> audioCapturerFilter,
355 std::vector<std::shared_ptr<AudioDeviceDescriptor>> selectedDesc)
356 {
357 AUDIO_WARNING_LOG("uid[%{public}d] type[%{public}d] mac[%{public}s] pid[%{public}d]",
358 audioCapturerFilter->uid, selectedDesc[0]->deviceType_,
359 GetEncryptAddr(selectedDesc[0]->macAddress_).c_str(), IPCSkeleton::GetCallingPid());
360 // check size == 1 && input device
361 int32_t res = audioDeviceCommon_.DeviceParamsCheck(DeviceRole::INPUT_DEVICE, selectedDesc);
362 CHECK_AND_RETURN_RET(res == SUCCESS, res);
363 if (audioCapturerFilter->uid != -1) {
364 audioAffinityManager_.AddSelectCapturerDevice(audioCapturerFilter->uid, selectedDesc[0]);
365 vector<shared_ptr<AudioCapturerChangeInfo>> capturerChangeInfos;
366 streamCollector_.GetCurrentCapturerChangeInfos(capturerChangeInfos);
367 for (auto &changeInfo : capturerChangeInfos) {
368 if (changeInfo->clientUID == audioCapturerFilter->uid && changeInfo->sessionId != 0) {
369 RestoreInfo restoreInfo;
370 restoreInfo.restoreReason = STREAM_SPLIT;
371 AudioServerProxy::GetInstance().RestoreSessionProxy(changeInfo->sessionId, restoreInfo);
372 }
373 }
374 return SUCCESS;
375 }
376
377 SourceType srcType = audioCapturerFilter->capturerInfo.sourceType;
378
379 if (audioCapturerFilter->capturerInfo.capturerFlags == STREAM_FLAG_FAST && selectedDesc.size() == 1) {
380 SetCaptureDeviceForUsage(audioSceneManager_.GetAudioScene(true), srcType, selectedDesc[0]);
381 int32_t result = SelectFastInputDevice(audioCapturerFilter, selectedDesc[0]);
382 CHECK_AND_RETURN_RET_LOG(result == SUCCESS, result,
383 "AddFastRouteMapInfo failed! fastRouteMap is too large!");
384 AUDIO_INFO_LOG("Success for uid[%{public}d] device[%{public}s]",
385 audioCapturerFilter->uid, GetEncryptStr(selectedDesc[0]->networkId_).c_str());
386 audioDeviceCommon_.FetchDevice(false);
387 audioCapturerSession_.ReloadSourceForDeviceChange(
388 audioActiveDevice_.GetCurrentInputDevice(),
389 audioActiveDevice_.GetCurrentOutputDevice(), "SelectInputDevice fast");
390 return SUCCESS;
391 }
392
393 AudioScene scene = audioSceneManager_.GetAudioScene(true);
394 if (scene == AUDIO_SCENE_PHONE_CALL || scene == AUDIO_SCENE_PHONE_CHAT ||
395 srcType == SOURCE_TYPE_VOICE_COMMUNICATION) {
396 AudioPolicyUtils::GetInstance().SetPreferredDevice(AUDIO_CALL_CAPTURE, selectedDesc[0]);
397 } else {
398 AudioPolicyUtils::GetInstance().SetPreferredDevice(AUDIO_RECORD_CAPTURE, selectedDesc[0]);
399 }
400 audioActiveDevice_.DisconnectScoWhenUserSelectInput(selectedDesc[0]);
401 audioDeviceCommon_.FetchDevice(false);
402
403 audioDeviceCommon_.OnPreferredInputDeviceUpdated(audioActiveDevice_.GetCurrentInputDeviceType(),
404 audioActiveDevice_.GetCurrentInputDevice().networkId_);
405 WriteSelectInputSysEvents(selectedDesc, srcType, scene);
406 audioCapturerSession_.ReloadSourceForDeviceChange(
407 audioActiveDevice_.GetCurrentInputDevice(),
408 audioActiveDevice_.GetCurrentOutputDevice(), "SelectInputDevice");
409 return SUCCESS;
410 }
411
ExcludeOutputDevices(AudioDeviceUsage audioDevUsage,std::vector<std::shared_ptr<AudioDeviceDescriptor>> & audioDeviceDescriptors)412 int32_t AudioRecoveryDevice::ExcludeOutputDevices(AudioDeviceUsage audioDevUsage,
413 std::vector<std::shared_ptr<AudioDeviceDescriptor>> &audioDeviceDescriptors)
414 {
415 AUDIO_WARNING_LOG("audioDevUsage[%{public}d], Exclude devices list size [%{public}zu], %{public}s",
416 audioDevUsage, audioDeviceDescriptors.size(),
417 AudioPolicyUtils::GetInstance().GetDevicesStr(audioDeviceDescriptors).c_str());
418
419 CHECK_AND_RETURN_RET_LOG(audioDeviceDescriptors.size() > 0, ERR_INVALID_PARAM, "No device to exclude");
420
421 if (audioDeviceDescriptors.front()->deviceType_ == DEVICE_TYPE_BLUETOOTH_SCO &&
422 audioDeviceDescriptors.front()->macAddress_.empty()) {
423 AudioPolicyUtils::GetInstance().SetScoExcluded(true);
424 return SUCCESS;
425 }
426
427 audioStateManager_.ExcludeOutputDevices(audioDevUsage, audioDeviceDescriptors);
428 shared_ptr<AudioDeviceDescriptor> userSelectedDevice = nullptr;
429 PreferredType preferredType = AUDIO_MEDIA_RENDER;
430 if (audioDevUsage == MEDIA_OUTPUT_DEVICES) {
431 userSelectedDevice = audioStateManager_.GetPreferredMediaRenderDevice();
432 } else if (audioDevUsage == CALL_OUTPUT_DEVICES) {
433 userSelectedDevice = audioStateManager_.GetPreferredCallRenderDevice();
434 preferredType = AUDIO_CALL_RENDER;
435 }
436 for (const auto &desc : audioDeviceDescriptors) {
437 CHECK_AND_RETURN_RET_LOG(desc != nullptr, ERR_INVALID_PARAM, "Invalid device descriptor");
438 if (userSelectedDevice != nullptr && desc->IsSameDeviceDesc(*userSelectedDevice)) {
439 AudioPolicyUtils::GetInstance().SetPreferredDevice(preferredType,
440 make_shared<AudioDeviceDescriptor>(), CLEAR_UID, "ExcludeOutputDevices");
441 }
442 WriteExcludeOutputSysEvents(audioDevUsage, desc);
443 }
444
445 audioDeviceCommon_.FetchDevice(true, AudioStreamDeviceChangeReason::OVERRODE);
446 audioDeviceCommon_.FetchDevice(false);
447 AudioDeviceDescriptor currentOutputDevice = audioActiveDevice_.GetCurrentOutputDevice();
448 AudioDeviceDescriptor currentInputDevice = audioActiveDevice_.GetCurrentInputDevice();
449 audioCapturerSession_.ReloadSourceForDeviceChange(
450 currentInputDevice, currentOutputDevice, "ExcludeOutputDevices");
451 if ((currentOutputDevice.deviceType_ != DEVICE_TYPE_BLUETOOTH_A2DP) ||
452 (currentOutputDevice.networkId_ != LOCAL_NETWORK_ID)) {
453 audioA2dpOffloadManager_->UpdateOffloadWhenActiveDeviceSwitchFromA2dp();
454 } else {
455 audioA2dpOffloadManager_->UpdateA2dpOffloadFlagForAllStream(currentOutputDevice.deviceType_);
456 }
457 audioDeviceCommon_.OnPreferredOutputDeviceUpdated(currentOutputDevice);
458 return SUCCESS;
459 }
460
UnexcludeOutputDevices(AudioDeviceUsage audioDevUsage,std::vector<std::shared_ptr<AudioDeviceDescriptor>> & audioDeviceDescriptors)461 int32_t AudioRecoveryDevice::UnexcludeOutputDevices(AudioDeviceUsage audioDevUsage,
462 std::vector<std::shared_ptr<AudioDeviceDescriptor>> &audioDeviceDescriptors)
463 {
464 if (audioDeviceDescriptors.front()->deviceType_ == DEVICE_TYPE_BLUETOOTH_SCO &&
465 audioDeviceDescriptors.front()->macAddress_.empty()) {
466 AudioPolicyUtils::GetInstance().SetScoExcluded(false);
467 return SUCCESS;
468 }
469 int32_t ret = UnexcludeOutputDevicesInner(audioDevUsage, audioDeviceDescriptors);
470 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Unexclude devices failed");
471
472 audioDeviceCommon_.FetchDevice(true, AudioStreamDeviceChangeReason::OVERRODE);
473 audioDeviceCommon_.FetchDevice(false);
474 AudioDeviceDescriptor currentOutputDevice = audioActiveDevice_.GetCurrentOutputDevice();
475 AudioDeviceDescriptor currentInputDevice = audioActiveDevice_.GetCurrentInputDevice();
476 audioCapturerSession_.ReloadSourceForDeviceChange(
477 currentInputDevice, currentOutputDevice, "UnexcludeOutputDevices");
478 if ((currentOutputDevice.deviceType_ != DEVICE_TYPE_BLUETOOTH_A2DP) ||
479 (currentOutputDevice.networkId_ != LOCAL_NETWORK_ID)) {
480 audioA2dpOffloadManager_->UpdateOffloadWhenActiveDeviceSwitchFromA2dp();
481 } else {
482 audioA2dpOffloadManager_->UpdateA2dpOffloadFlagForAllStream(currentOutputDevice.deviceType_);
483 }
484 audioDeviceCommon_.OnPreferredOutputDeviceUpdated(currentOutputDevice);
485 return SUCCESS;
486 }
487
UnexcludeOutputDevicesInner(AudioDeviceUsage audioDevUsage,std::vector<std::shared_ptr<AudioDeviceDescriptor>> & audioDeviceDescriptors)488 int32_t AudioRecoveryDevice::UnexcludeOutputDevicesInner(AudioDeviceUsage audioDevUsage,
489 std::vector<std::shared_ptr<AudioDeviceDescriptor>> &audioDeviceDescriptors)
490 {
491 AUDIO_WARNING_LOG("audioDevUsage[%{public}d], Unexclude devices list size [%{public}zu], %{public}s",
492 audioDevUsage, audioDeviceDescriptors.size(),
493 AudioPolicyUtils::GetInstance().GetDevicesStr(audioDeviceDescriptors).c_str());
494
495 CHECK_AND_RETURN_RET_LOG(audioDeviceDescriptors.size() > 0, ERR_INVALID_PARAM, "No device to exclude");
496
497 for (const auto &desc : audioDeviceDescriptors) {
498 CHECK_AND_RETURN_RET_LOG(desc != nullptr, ERR_INVALID_PARAM, "Invalid device descriptor");
499 WriteUnexcludeOutputSysEvents(audioDevUsage, desc);
500 }
501
502 audioStateManager_.UnexcludeOutputDevices(audioDevUsage, audioDeviceDescriptors);
503 return SUCCESS;
504 }
505
SetCaptureDeviceForUsage(AudioScene scene,SourceType srcType,std::shared_ptr<AudioDeviceDescriptor> desc)506 void AudioRecoveryDevice::SetCaptureDeviceForUsage(AudioScene scene, SourceType srcType,
507 std::shared_ptr<AudioDeviceDescriptor> desc)
508 {
509 AUDIO_INFO_LOG("Scene: %{public}d, srcType: %{public}d", scene, srcType);
510 if (scene == AUDIO_SCENE_PHONE_CALL || scene == AUDIO_SCENE_PHONE_CHAT ||
511 srcType == SOURCE_TYPE_VOICE_COMMUNICATION) {
512 AudioPolicyUtils::GetInstance().SetPreferredDevice(AUDIO_CALL_CAPTURE, desc);
513 } else {
514 AudioPolicyUtils::GetInstance().SetPreferredDevice(AUDIO_RECORD_CAPTURE, desc);
515 }
516 }
517
SelectFastInputDevice(sptr<AudioCapturerFilter> audioCapturerFilter,std::shared_ptr<AudioDeviceDescriptor> deviceDescriptor)518 int32_t AudioRecoveryDevice::SelectFastInputDevice(sptr<AudioCapturerFilter> audioCapturerFilter,
519 std::shared_ptr<AudioDeviceDescriptor> deviceDescriptor)
520 {
521 // note: check if stream is already running
522 // if is running, call moveProcessToEndpoint.
523
524 // otherwises, keep router info in the map
525 int32_t res = audioRouteMap_.AddFastRouteMapInfo(audioCapturerFilter->uid,
526 deviceDescriptor->networkId_, INPUT_DEVICE);
527 return res;
528 }
529
WriteSelectInputSysEvents(const std::vector<std::shared_ptr<AudioDeviceDescriptor>> & selectedDesc,SourceType srcType,AudioScene scene)530 void AudioRecoveryDevice::WriteSelectInputSysEvents(
531 const std::vector<std::shared_ptr<AudioDeviceDescriptor>> &selectedDesc,
532 SourceType srcType, AudioScene scene)
533 {
534 auto uid = IPCSkeleton::GetCallingUid();
535 std::shared_ptr<Media::MediaMonitor::EventBean> bean = std::make_shared<Media::MediaMonitor::EventBean>(
536 Media::MediaMonitor::AUDIO, Media::MediaMonitor::SET_FORCE_USE_AUDIO_DEVICE,
537 Media::MediaMonitor::BEHAVIOR_EVENT);
538 bean->Add("CLIENT_UID", static_cast<int32_t>(uid));
539 bean->Add("DEVICE_TYPE", selectedDesc[0]->deviceType_);
540 bean->Add("STREAM_TYPE", srcType);
541 bean->Add("BT_TYPE", selectedDesc[0]->deviceCategory_);
542 bean->Add("DEVICE_NAME", selectedDesc[0]->deviceName_);
543 bean->Add("ADDRESS", selectedDesc[0]->macAddress_);
544 bean->Add("AUDIO_SCENE", scene);
545 bean->Add("IS_PLAYBACK", 0);
546 Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
547 }
548
WriteExcludeOutputSysEvents(const AudioDeviceUsage audioDevUsage,const std::shared_ptr<AudioDeviceDescriptor> & desc)549 void AudioRecoveryDevice::WriteExcludeOutputSysEvents(const AudioDeviceUsage audioDevUsage,
550 const std::shared_ptr<AudioDeviceDescriptor> &desc)
551 {
552 int64_t timeStamp = AudioPolicyUtils::GetInstance().GetCurrentTimeMS();
553 auto uid = IPCSkeleton::GetCallingUid();
554 shared_ptr<Media::MediaMonitor::EventBean> bean = make_shared<Media::MediaMonitor::EventBean>(
555 Media::MediaMonitor::AUDIO, Media::MediaMonitor::EXCLUDE_OUTPUT_DEVICE,
556 Media::MediaMonitor::BEHAVIOR_EVENT);
557 bean->Add("CLIENT_UID", static_cast<int32_t>(uid));
558 bean->Add("TIME_STAMP", static_cast<uint64_t>(timeStamp));
559 bean->Add("EXCLUSION_STATUS", EXCLUDED);
560 bean->Add("AUDIO_DEVICE_USAGE", static_cast<int32_t>(audioDevUsage));
561 bean->Add("DEVICE_TYPE", desc->deviceType_);
562 bean->Add("NETWORKID", desc->networkId_);
563 bean->Add("ADDRESS", desc->macAddress_);
564 bean->Add("DEVICE_NAME", desc->deviceName_);
565 bean->Add("BT_TYPE", desc->deviceCategory_);
566 Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
567 }
568
WriteUnexcludeOutputSysEvents(const AudioDeviceUsage audioDevUsage,const std::shared_ptr<AudioDeviceDescriptor> & desc)569 void AudioRecoveryDevice::WriteUnexcludeOutputSysEvents(const AudioDeviceUsage audioDevUsage,
570 const std::shared_ptr<AudioDeviceDescriptor> &desc)
571 {
572 int64_t timeStamp = AudioPolicyUtils::GetInstance().GetCurrentTimeMS();
573 auto uid = IPCSkeleton::GetCallingUid();
574 shared_ptr<Media::MediaMonitor::EventBean> bean = make_shared<Media::MediaMonitor::EventBean>(
575 Media::MediaMonitor::AUDIO, Media::MediaMonitor::EXCLUDE_OUTPUT_DEVICE,
576 Media::MediaMonitor::BEHAVIOR_EVENT);
577 bean->Add("CLIENT_UID", static_cast<int32_t>(uid));
578 bean->Add("TIME_STAMP", static_cast<uint64_t>(timeStamp));
579 bean->Add("EXCLUSION_STATUS", UNEXCLUDED);
580 bean->Add("AUDIO_DEVICE_USAGE", static_cast<int32_t>(audioDevUsage));
581 bean->Add("DEVICE_TYPE", desc->deviceType_);
582 bean->Add("NETWORKID", desc->networkId_);
583 bean->Add("ADDRESS", desc->macAddress_);
584 bean->Add("DEVICE_NAME", desc->deviceName_);
585 bean->Add("BT_TYPE", desc->deviceCategory_);
586 Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
587 }
588 } // namespace AudioStandard
589 } // namespace OHOS
590