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