• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright (c) 2021-2025 Huawei Device Co., Ltd.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #ifndef LOG_TAG
17 #define LOG_TAG "AudioActiveDevice"
18 #endif
19 
20 #include "audio_active_device.h"
21 #include <ability_manager_client.h>
22 #include "iservice_registry.h"
23 #include "parameter.h"
24 #include "parameters.h"
25 #include "audio_policy_log.h"
26 #include "audio_manager_listener_stub.h"
27 #include "audio_inner_call.h"
28 #include "media_monitor_manager.h"
29 
30 #ifdef BLUETOOTH_ENABLE
31 #include "audio_server_death_recipient.h"
32 #include "audio_bluetooth_manager.h"
33 #include "bluetooth_device_manager.h"
34 #endif
35 
36 #include "audio_policy_utils.h"
37 #include "audio_server_proxy.h"
38 
39 namespace OHOS {
40 namespace AudioStandard {
41 
42 #ifdef BLUETOOTH_ENABLE
43 const uint32_t USER_NOT_SELECT_BT = 1;
44 const uint32_t USER_SELECT_BT = 2;
45 #endif
46 
GetActiveA2dpDeviceStreamInfo(DeviceType deviceType,AudioStreamInfo & streamInfo)47 bool AudioActiveDevice::GetActiveA2dpDeviceStreamInfo(DeviceType deviceType, AudioStreamInfo &streamInfo)
48 {
49     if (deviceType == DEVICE_TYPE_BLUETOOTH_A2DP) {
50         A2dpDeviceConfigInfo info;
51         if (audioA2dpDevice_.GetA2dpDeviceInfo(activeBTDevice_, info)) {
52             streamInfo.samplingRate = *info.streamInfo.samplingRate.rbegin();
53             streamInfo.format = info.streamInfo.format;
54             streamInfo.channels = *info.streamInfo.channels.rbegin();
55             return true;
56         }
57     } else if (deviceType == DEVICE_TYPE_BLUETOOTH_A2DP_IN) {
58         A2dpDeviceConfigInfo info;
59         if (audioA2dpDevice_.GetA2dpInDeviceInfo(activeBTInDevice_, info)) {
60             streamInfo.samplingRate = *info.streamInfo.samplingRate.rbegin();
61             streamInfo.format = info.streamInfo.format;
62             streamInfo.channels = *info.streamInfo.channels.rbegin();
63             return true;
64         }
65     }
66     return false;
67 }
68 
GetActiveBtDeviceMac()69 std::string AudioActiveDevice::GetActiveBtDeviceMac()
70 {
71     return activeBTDevice_;
72 }
73 
SetActiveBtDeviceMac(const std::string macAddress)74 void AudioActiveDevice::SetActiveBtDeviceMac(const std::string macAddress)
75 {
76     activeBTDevice_ = macAddress;
77 }
78 
SetActiveBtInDeviceMac(const std::string macAddress)79 void AudioActiveDevice::SetActiveBtInDeviceMac(const std::string macAddress)
80 {
81     activeBTInDevice_ = macAddress;
82 }
83 
IsDirectSupportedDevice()84 bool AudioActiveDevice::IsDirectSupportedDevice()
85 {
86     DeviceType dev = GetCurrentOutputDeviceType();
87     return dev == DEVICE_TYPE_WIRED_HEADSET || dev == DEVICE_TYPE_USB_HEADSET;
88 }
89 
CheckActiveOutputDeviceSupportOffload()90 bool AudioActiveDevice::CheckActiveOutputDeviceSupportOffload()
91 {
92     DeviceType dev = GetCurrentOutputDeviceType();
93     if (GetCurrentOutputDeviceNetworkId() != LOCAL_NETWORK_ID || dev == DEVICE_TYPE_REMOTE_CAST) {
94         return false;
95     }
96 
97     return dev == DEVICE_TYPE_SPEAKER ||
98         (dev == DEVICE_TYPE_BLUETOOTH_A2DP && audioA2dpOffloadFlag_.GetA2dpOffloadFlag() == A2DP_OFFLOAD) ||
99         dev == DEVICE_TYPE_USB_HEADSET;
100 }
101 
SetCurrentInputDevice(const AudioDeviceDescriptor & desc)102 void AudioActiveDevice::SetCurrentInputDevice(const AudioDeviceDescriptor &desc)
103 {
104     std::lock_guard<std::mutex> lock(curInputDevice_);
105     currentActiveInputDevice_ = AudioDeviceDescriptor(desc);
106 }
107 
GetCurrentInputDevice()108 const AudioDeviceDescriptor& AudioActiveDevice::GetCurrentInputDevice()
109 {
110     std::lock_guard<std::mutex> lock(curInputDevice_);
111     return currentActiveInputDevice_;
112 }
113 
114 
GetCurrentInputDeviceType()115 DeviceType AudioActiveDevice::GetCurrentInputDeviceType()
116 {
117     std::lock_guard<std::mutex> lock(curInputDevice_);
118     return currentActiveInputDevice_.deviceType_;
119 }
120 
SetCurrentInputDeviceType(DeviceType deviceType)121 void AudioActiveDevice::SetCurrentInputDeviceType(DeviceType deviceType)
122 {
123     std::lock_guard<std::mutex> lock(curInputDevice_);
124     currentActiveInputDevice_.deviceType_ = deviceType;
125 }
126 
GetCurrentInputDeviceMacAddr()127 std::string AudioActiveDevice::GetCurrentInputDeviceMacAddr()
128 {
129     std::lock_guard<std::mutex> lock(curInputDevice_);
130     return currentActiveDevice_.macAddress_;
131 }
132 
SetCurrentOutputDevice(const AudioDeviceDescriptor & desc)133 void AudioActiveDevice::SetCurrentOutputDevice(const AudioDeviceDescriptor &desc)
134 {
135     std::lock_guard<std::mutex> lock(curOutputDevice_);
136     currentActiveDevice_ = AudioDeviceDescriptor(desc);
137 }
138 
SetCurrentOutputDeviceType(DeviceType deviceType)139 void AudioActiveDevice::SetCurrentOutputDeviceType(DeviceType deviceType)
140 {
141     std::lock_guard<std::mutex> lock(curOutputDevice_);
142     currentActiveDevice_.deviceType_ = deviceType;
143 }
144 
GetCurrentOutputDevice()145 const AudioDeviceDescriptor& AudioActiveDevice::GetCurrentOutputDevice()
146 {
147     std::lock_guard<std::mutex> lock(curOutputDevice_);
148     return currentActiveDevice_;
149 }
150 
GetCurrentOutputDeviceType()151 DeviceType AudioActiveDevice::GetCurrentOutputDeviceType()
152 {
153     std::lock_guard<std::mutex> lock(curOutputDevice_);
154     return currentActiveDevice_.deviceType_;
155 }
156 
GetCurrentOutputDeviceCategory()157 DeviceCategory AudioActiveDevice::GetCurrentOutputDeviceCategory()
158 {
159     std::lock_guard<std::mutex> lock(curOutputDevice_);
160     return currentActiveDevice_.deviceCategory_;
161 }
162 
GetCurrentOutputDeviceNetworkId()163 std::string AudioActiveDevice::GetCurrentOutputDeviceNetworkId()
164 {
165     std::lock_guard<std::mutex> lock(curOutputDevice_);
166     return currentActiveDevice_.networkId_;
167 }
168 
GetCurrentOutputDeviceMacAddr()169 std::string AudioActiveDevice::GetCurrentOutputDeviceMacAddr()
170 {
171     std::lock_guard<std::mutex> lock(curOutputDevice_);
172     return currentActiveDevice_.macAddress_;
173 }
174 
GetMaxAmplitude(const int32_t deviceId,AudioInterrupt audioInterrupt)175 float AudioActiveDevice::GetMaxAmplitude(const int32_t deviceId, AudioInterrupt audioInterrupt)
176 {
177     AudioDeviceDescriptor descriptor = GetCurrentOutputDevice();
178     if (deviceId == descriptor.deviceId_) {
179         uint32_t sessionId = audioInterrupt.streamId;
180         std::string sinkName = AudioPolicyUtils::GetInstance().GetSinkName(descriptor, static_cast<int32_t>(sessionId));
181         std::string deviceClass = AudioPolicyUtils::GetInstance().GetOutputDeviceClassBySinkPortName(sinkName);
182         return AudioServerProxy::GetInstance().GetMaxAmplitudeProxy(true, deviceClass);
183     }
184 
185     descriptor = GetCurrentInputDevice();
186     if (deviceId == descriptor.deviceId_) {
187         std::string sourceName = AudioPolicyUtils::GetInstance().GetSourcePortName(GetCurrentInputDeviceType());
188         std::string deviceClass = AudioPolicyUtils::GetInstance().GetInputDeviceClassBySourcePortName(sourceName);
189         return AudioServerProxy::GetInstance().GetMaxAmplitudeProxy(false, deviceClass,
190             audioInterrupt.audioFocusType.sourceType);
191     }
192 
193     return 0;
194 }
195 
NotifyUserSelectionEventToBt(std::shared_ptr<AudioDeviceDescriptor> audioDeviceDescriptor)196 void AudioActiveDevice::NotifyUserSelectionEventToBt(std::shared_ptr<AudioDeviceDescriptor> audioDeviceDescriptor)
197 {
198     Trace trace("AudioActiveDevice::NotifyUserSelectionEventToBt");
199     if (audioDeviceDescriptor == nullptr) {
200         return;
201     }
202 #ifdef BLUETOOTH_ENABLE
203     DeviceType curOutputDeviceType = GetCurrentOutputDeviceType();
204     if (curOutputDeviceType == DEVICE_TYPE_BLUETOOTH_SCO ||
205         curOutputDeviceType == DEVICE_TYPE_BLUETOOTH_A2DP) {
206         Bluetooth::SendUserSelectionEvent(curOutputDeviceType,
207             GetCurrentOutputDeviceMacAddr(), USER_NOT_SELECT_BT);
208         if (curOutputDeviceType == DEVICE_TYPE_BLUETOOTH_SCO) {
209             Bluetooth::AudioHfpManager::DisconnectSco();
210         }
211     }
212     if (audioDeviceDescriptor->deviceType_ == DEVICE_TYPE_BLUETOOTH_SCO ||
213         audioDeviceDescriptor->deviceType_ == DEVICE_TYPE_BLUETOOTH_A2DP) {
214         Bluetooth::SendUserSelectionEvent(audioDeviceDescriptor->deviceType_,
215             audioDeviceDescriptor->macAddress_, USER_SELECT_BT);
216     }
217 #endif
218 }
219 
DisconnectScoWhenUserSelectInput(std::shared_ptr<AudioDeviceDescriptor> audioDeviceDescriptor)220 void AudioActiveDevice::DisconnectScoWhenUserSelectInput(std::shared_ptr<AudioDeviceDescriptor> audioDeviceDescriptor)
221 {
222     if (audioDeviceDescriptor == nullptr) {
223         AUDIO_ERR_LOG("nullptr audioDeviceDescriptor");
224         return;
225     }
226 #ifdef BLUETOOTH_ENABLE
227     DeviceType curInputDeviceType = GetCurrentInputDeviceType();
228     if (curInputDeviceType == DEVICE_TYPE_BLUETOOTH_SCO) {
229         AUDIO_INFO_LOG("user select ready to disconnect");
230         Bluetooth::AudioHfpManager::DisconnectSco();
231     }
232 #endif
233 }
234 
WriteOutputRouteChangeEvent(std::shared_ptr<AudioDeviceDescriptor> & desc,const AudioStreamDeviceChangeReason reason)235 void AudioActiveDevice::WriteOutputRouteChangeEvent(std::shared_ptr<AudioDeviceDescriptor> &desc,
236     const AudioStreamDeviceChangeReason reason)
237 {
238     int64_t timeStamp = AudioPolicyUtils::GetInstance().GetCurrentTimeMS();
239     std::shared_ptr<Media::MediaMonitor::EventBean> bean = std::make_shared<Media::MediaMonitor::EventBean>(
240         Media::MediaMonitor::AUDIO, Media::MediaMonitor::AUDIO_ROUTE_CHANGE,
241         Media::MediaMonitor::BEHAVIOR_EVENT);
242     DeviceType curOutputDeviceType = GetCurrentOutputDeviceType();
243     bean->Add("REASON", static_cast<int32_t>(reason));
244     bean->Add("TIMESTAMP", static_cast<uint64_t>(timeStamp));
245     bean->Add("DEVICE_TYPE_BEFORE_CHANGE", curOutputDeviceType);
246     bean->Add("DEVICE_TYPE_AFTER_CHANGE", desc->deviceType_);
247     Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
248 }
249 
UpdateDevice(std::shared_ptr<AudioDeviceDescriptor> & desc,const AudioStreamDeviceChangeReasonExt reason,const std::shared_ptr<AudioRendererChangeInfo> & rendererChangeInfo)250 bool AudioActiveDevice::UpdateDevice(std::shared_ptr<AudioDeviceDescriptor> &desc,
251     const AudioStreamDeviceChangeReasonExt reason, const std::shared_ptr<AudioRendererChangeInfo> &rendererChangeInfo)
252 {
253     std::shared_ptr<AudioDeviceDescriptor> preferredDesc =
254         audioAffinityManager_.GetRendererDevice(rendererChangeInfo->clientUID);
255     AudioDeviceDescriptor tmpOutputDeviceDesc = GetCurrentOutputDevice();
256     if (((preferredDesc->deviceType_ != DEVICE_TYPE_NONE) && !desc->IsSameDeviceInfo(tmpOutputDeviceDesc)
257         && desc->deviceType_ != preferredDesc->deviceType_)
258         || ((preferredDesc->deviceType_ == DEVICE_TYPE_NONE) && !desc->IsSameDeviceInfo(tmpOutputDeviceDesc))) {
259         WriteOutputRouteChangeEvent(desc, reason);
260         SetCurrentOutputDevice(*desc);
261         AUDIO_DEBUG_LOG("currentActiveDevice update %{public}d", GetCurrentOutputDeviceType());
262         return true;
263     }
264     return false;
265 }
266 
HandleActiveBt(DeviceType deviceType,std::string macAddress)267 void AudioActiveDevice::HandleActiveBt(DeviceType deviceType, std::string macAddress)
268 {
269     if (GetCurrentOutputDeviceType() == DEVICE_TYPE_BLUETOOTH_SCO &&
270         deviceType != DEVICE_TYPE_BLUETOOTH_SCO) {
271         Bluetooth::SendUserSelectionEvent(DEVICE_TYPE_BLUETOOTH_SCO,
272             GetCurrentOutputDeviceMacAddr(), USER_NOT_SELECT_BT);
273         Bluetooth::AudioHfpManager::DisconnectSco();
274     }
275     if (GetCurrentOutputDeviceType() != DEVICE_TYPE_BLUETOOTH_SCO &&
276         deviceType == DEVICE_TYPE_BLUETOOTH_SCO) {
277         Bluetooth::SendUserSelectionEvent(DEVICE_TYPE_BLUETOOTH_SCO,
278             macAddress, USER_SELECT_BT);
279     }
280 }
281 
HandleNegtiveBt(DeviceType deviceType)282 void AudioActiveDevice::HandleNegtiveBt(DeviceType deviceType)
283 {
284     if (GetCurrentOutputDeviceType() == DEVICE_TYPE_BLUETOOTH_SCO &&
285         deviceType == DEVICE_TYPE_BLUETOOTH_SCO) {
286         Bluetooth::SendUserSelectionEvent(DEVICE_TYPE_BLUETOOTH_SCO,
287             GetCurrentOutputDeviceMacAddr(), USER_NOT_SELECT_BT);
288         Bluetooth::AudioHfpManager::DisconnectSco();
289     }
290 }
291 
IsDeviceActive(DeviceType deviceType)292 bool AudioActiveDevice::IsDeviceActive(DeviceType deviceType)
293 {
294     AUDIO_DEBUG_LOG("type [%{public}d]", deviceType);
295     CHECK_AND_RETURN_RET(GetCurrentOutputDeviceNetworkId() == LOCAL_NETWORK_ID, false);
296     return GetCurrentOutputDeviceType() == deviceType;
297 }
298 
UpdateInputDeviceInfo(DeviceType deviceType)299 void AudioActiveDevice::UpdateInputDeviceInfo(DeviceType deviceType)
300 {
301     DeviceType curType = GetCurrentInputDeviceType();
302     switch (deviceType) {
303         case DEVICE_TYPE_EARPIECE:
304         case DEVICE_TYPE_SPEAKER:
305         case DEVICE_TYPE_BLUETOOTH_A2DP:
306             curType = DEVICE_TYPE_MIC;
307             break;
308         case DEVICE_TYPE_FILE_SINK:
309             curType = DEVICE_TYPE_FILE_SOURCE;
310             break;
311         case DEVICE_TYPE_USB_ARM_HEADSET:
312             curType = DEVICE_TYPE_USB_HEADSET;
313             break;
314         case DEVICE_TYPE_WIRED_HEADSET:
315         case DEVICE_TYPE_USB_HEADSET:
316         case DEVICE_TYPE_BLUETOOTH_SCO:
317             curType = deviceType;
318             break;
319         default:
320             break;
321     }
322 
323     SetCurrentInputDeviceType(curType);
324 
325     AUDIO_INFO_LOG("Input device updated to %{public}d", curType);
326 }
327 
SetDeviceActive(DeviceType deviceType,bool active,const int32_t uid)328 int32_t AudioActiveDevice::SetDeviceActive(DeviceType deviceType, bool active, const int32_t uid)
329 {
330     CHECK_AND_RETURN_RET_LOG(deviceType != DEVICE_TYPE_NONE, ERR_DEVICE_NOT_SUPPORTED, "Invalid device");
331 
332     // Activate new device if its already connected
333     auto isPresent = [&deviceType] (const std::shared_ptr<AudioDeviceDescriptor> &desc) {
334         CHECK_AND_RETURN_RET_LOG(desc != nullptr, false, "SetDeviceActive::Invalid device descriptor");
335         return ((deviceType == desc->deviceType_) || (deviceType == DEVICE_TYPE_FILE_SINK));
336     };
337 
338     std::vector<std::shared_ptr<AudioDeviceDescriptor>> callDevices
339         = AudioPolicyUtils::GetInstance().GetAvailableDevicesInner(CALL_OUTPUT_DEVICES);
340     std::vector<std::shared_ptr<AudioDeviceDescriptor>> deviceList = {};
341     for (const auto &desc : callDevices) {
342         std::shared_ptr<AudioDeviceDescriptor> devDesc = std::make_shared<AudioDeviceDescriptor>(*desc);
343         deviceList.push_back(devDesc);
344     }
345 
346     auto itr = std::find_if(deviceList.begin(), deviceList.end(), isPresent);
347     CHECK_AND_RETURN_RET_LOG(itr != deviceList.end(), ERR_OPERATION_FAILED,
348         "Requested device not available %{public}d ", deviceType);
349     if (!active) {
350         AudioPolicyUtils::GetInstance().SetPreferredDevice(AUDIO_CALL_RENDER,
351             std::make_shared<AudioDeviceDescriptor>(), uid, "SetDeviceActive");
352 #ifdef BLUETOOTH_ENABLE
353         HandleNegtiveBt(deviceType);
354 #endif
355     } else {
356         AudioPolicyUtils::GetInstance().SetPreferredDevice(AUDIO_CALL_RENDER, *itr, uid, "SetDeviceActive");
357 #ifdef BLUETOOTH_ENABLE
358         HandleActiveBt(deviceType, (*itr)->macAddress_);
359 #endif
360     }
361     return SUCCESS;
362 }
363 
SetCallDeviceActive(DeviceType deviceType,bool active,std::string address,const int32_t uid)364 int32_t AudioActiveDevice::SetCallDeviceActive(DeviceType deviceType, bool active, std::string address,
365     const int32_t uid)
366 {
367     // Activate new device if its already connected
368     auto isPresent = [&deviceType, &address] (const std::shared_ptr<AudioDeviceDescriptor> &desc) {
369         CHECK_AND_RETURN_RET_LOG(desc != nullptr, false, "Invalid device descriptor");
370         return ((deviceType == desc->deviceType_) && (address == desc->macAddress_));
371     };
372     std::vector<std::shared_ptr<AudioDeviceDescriptor>> callDevices
373         = AudioPolicyUtils::GetInstance().GetAvailableDevicesInner(CALL_OUTPUT_DEVICES);
374 
375     auto itr = std::find_if(callDevices.begin(), callDevices.end(), isPresent);
376     CHECK_AND_RETURN_RET_LOG(itr != callDevices.end(), ERR_OPERATION_FAILED,
377         "Requested device not available %{public}d ", deviceType);
378     if (active) {
379         if (deviceType == DEVICE_TYPE_BLUETOOTH_SCO) {
380             (*itr)->isEnable_ = true;
381             audioDeviceManager_.UpdateDevicesListInfo(std::make_shared<AudioDeviceDescriptor>(**itr), ENABLE_UPDATE);
382             AudioPolicyUtils::GetInstance().ClearScoDeviceSuspendState(address);
383         }
384         AudioPolicyUtils::GetInstance().SetPreferredDevice(AUDIO_CALL_RENDER,
385             std::make_shared<AudioDeviceDescriptor>(**itr), uid, "SetCallDeviceActive");
386 #ifdef BLUETOOTH_ENABLE
387         HandleActiveBt(deviceType, (*itr)->macAddress_);
388 #endif
389     } else {
390         AudioPolicyUtils::GetInstance().SetPreferredDevice(AUDIO_CALL_RENDER,
391             std::make_shared<AudioDeviceDescriptor>(), uid, "SetCallDeviceActive");
392 #ifdef BLUETOOTH_ENABLE
393         HandleNegtiveBt(deviceType);
394 #endif
395     }
396     return SUCCESS;
397 }
398 
UpdateActiveDeviceRoute(DeviceType deviceType,DeviceFlag deviceFlag,const std::string & deviceName)399 void AudioActiveDevice::UpdateActiveDeviceRoute(DeviceType deviceType, DeviceFlag deviceFlag,
400     const std::string &deviceName)
401 {
402     Trace trace("AudioActiveDevice::UpdateActiveDeviceRoute DeviceType:" + std::to_string(deviceType));
403     AUDIO_INFO_LOG("Active route with type[%{public}d] name[%{public}s]", deviceType, deviceName.c_str());
404     std::vector<std::pair<DeviceType, DeviceFlag>> activeDevices;
405     activeDevices.push_back(make_pair(deviceType, deviceFlag));
406     UpdateActiveDevicesRoute(activeDevices, deviceName);
407 }
408 
UpdateActiveDevicesRoute(std::vector<std::pair<DeviceType,DeviceFlag>> & activeDevices,const std::string & deviceName)409 void AudioActiveDevice::UpdateActiveDevicesRoute(std::vector<std::pair<DeviceType, DeviceFlag>>
410     &activeDevices, const std::string &deviceName)
411 {
412     CHECK_AND_RETURN_LOG(!activeDevices.empty(), "activeDevices is empty.");
413     auto ret = SUCCESS;
414     std::string deviceTypesInfo = "";
415     for (size_t i = 0; i < activeDevices.size(); i++) {
416         deviceTypesInfo = deviceTypesInfo + " " + std::to_string(activeDevices[i].first);
417         AUDIO_INFO_LOG("update active devices, device type info:[%{public}s]",
418             std::to_string(activeDevices[i].first).c_str());
419     }
420 
421     Trace trace("AudioActiveDevice::UpdateActiveDevicesRoute DeviceTypes:" + deviceTypesInfo);
422     ret = AudioServerProxy::GetInstance().UpdateActiveDevicesRouteProxy(activeDevices,
423         audioA2dpOffloadFlag_.GetA2dpOffloadFlag(), deviceName);
424     CHECK_AND_RETURN_LOG(ret == SUCCESS, "Failed to update the route for %{public}s", deviceTypesInfo.c_str());
425 }
426 
427 }
428 }
429