• 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 
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