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 "DeviceStatusListener"
17 #endif
18
19 #include "device_status_listener.h"
20 #include <securec.h>
21 #include <cstring>
22 #include "hdf_device_class.h"
23 #include "v4_0/audio_types.h"
24
25 #ifdef BLUETOOTH_ENABLE
26
27 #include "audio_bluetooth_manager.h"
28 #include "bluetooth_def.h"
29
30 #endif
31
32 #include "audio_errors.h"
33 #include "audio_policy_log.h"
34
35 namespace OHOS {
36 namespace AudioStandard {
37 const std::string AUDIO_HDI_SERVICE_NAME = "audio_manager_service";
38 const std::string AUDIO_HDI_PNP_SERVICE_NAME = "audio_hdi_pnp_service";
39 const std::string AUDIO_BLUETOOTH_HDI_SERVICE_NAME = "audio_bluetooth_hdi_service";
40 const std::string DAUDIO_HDI_SERVICE_NAME = "daudio_primary_service";
41 const std::string DP_ADDRESS = "card=0;port=";
42 const uint8_t EVENT_NUM_TYPE = 2;
43 const uint8_t EVENT_PARAMS = 4;
44 const uint8_t D_EVENT_PARAMS = 5;
45
GetInternalDeviceType(PnpDeviceType pnpDeviceType)46 static DeviceType GetInternalDeviceType(PnpDeviceType pnpDeviceType)
47 {
48 DeviceType internalDeviceType = DEVICE_TYPE_NONE;
49
50 switch (pnpDeviceType) {
51 case PnpDeviceType::PNP_DEVICE_HEADSET:
52 internalDeviceType = DEVICE_TYPE_WIRED_HEADSET;
53 break;
54 case PnpDeviceType::PNP_DEVICE_HEADPHONE:
55 internalDeviceType = DEVICE_TYPE_WIRED_HEADPHONES;
56 break;
57 case PnpDeviceType::PNP_DEVICE_USB_HEADSET:
58 internalDeviceType = DEVICE_TYPE_USB_HEADSET;
59 break;
60 case PnpDeviceType::PNP_DEVICE_ADAPTER_DEVICE:
61 internalDeviceType = DEVICE_TYPE_EXTERN_CABLE;
62 break;
63 case PnpDeviceType::PNP_DEVICE_DP_DEVICE:
64 internalDeviceType = DEVICE_TYPE_DP;
65 break;
66 case PnpDeviceType::PNP_DEVICE_MIC:
67 internalDeviceType = DEVICE_TYPE_MIC;
68 break;
69 case PnpDeviceType::PNP_DEVICE_HDMI_DEVICE:
70 internalDeviceType = DEVICE_TYPE_HDMI;
71 break;
72 default:
73 internalDeviceType = DEVICE_TYPE_NONE;
74 break;
75 }
76
77 return internalDeviceType;
78 }
79
ReceviceDistributedInfo(struct ServiceStatus * serviceStatus,std::string & info,DeviceStatusListener * devListener)80 static void ReceviceDistributedInfo(struct ServiceStatus* serviceStatus, std::string & info,
81 DeviceStatusListener * devListener)
82 {
83 if (serviceStatus->status == SERVIE_STATUS_START) {
84 AUDIO_DEBUG_LOG("distributed service online");
85 } else if (serviceStatus->status == SERVIE_STATUS_CHANGE && !info.empty()) {
86 DStatusInfo statusInfo;
87 statusInfo.connectType = ConnectType::CONNECT_TYPE_DISTRIBUTED;
88 PnpEventType pnpEventType = PNP_EVENT_UNKNOWN;
89 if (sscanf_s(info.c_str(), "EVENT_TYPE=%d;NID=%[^;];PIN=%d;VID=%d;IID=%d", &pnpEventType,
90 statusInfo.networkId, sizeof(statusInfo.networkId), &(statusInfo.hdiPin), &(statusInfo.mappingVolumeId),
91 &(statusInfo.mappingInterruptId)) < D_EVENT_PARAMS) {
92 AUDIO_ERR_LOG("[DeviceStatusListener]: Failed to scan info string");
93 return;
94 }
95
96 statusInfo.isConnected = (pnpEventType == PNP_EVENT_DEVICE_ADD) ? true : false;
97 devListener->deviceObserver_.OnDeviceStatusUpdated(statusInfo);
98 } else if (serviceStatus->status == SERVIE_STATUS_STOP) {
99 AUDIO_DEBUG_LOG("distributed service offline");
100 DStatusInfo statusInfo;
101 devListener->deviceObserver_.OnDeviceStatusUpdated(statusInfo, true);
102 }
103 }
104
OnDeviceStatusChange(const std::string & info,DeviceStatusListener * devListener)105 static void OnDeviceStatusChange(const std::string &info, DeviceStatusListener *devListener)
106 {
107 CHECK_AND_RETURN_LOG(!info.empty(), "OnDeviceStatusChange invalid info");
108 PnpDeviceType pnpDeviceType = PNP_DEVICE_UNKNOWN;
109 PnpEventType pnpEventType = PNP_EVENT_UNKNOWN;
110 if (sscanf_s(info.c_str(), "EVENT_TYPE=%d;DEVICE_TYPE=%d", &pnpEventType, &pnpDeviceType) < EVENT_PARAMS) {
111 AUDIO_WARNING_LOG("[DeviceStatusListener]: Failed to scan info string %{public}s", info.c_str());
112 return;
113 }
114
115 DeviceType internalDevice = GetInternalDeviceType(pnpDeviceType);
116 AUDIO_DEBUG_LOG("internalDevice = %{public}d, pnpDeviceType = %{public}d", internalDevice, pnpDeviceType);
117 if (internalDevice == DEVICE_TYPE_NONE) {
118 AUDIO_DEBUG_LOG("Unsupported device %{public}d", pnpDeviceType);
119 return;
120 }
121 bool isConnected = (pnpEventType == PNP_EVENT_DEVICE_ADD) ? true : false;
122 AudioStreamInfo streamInfo = {};
123 devListener->deviceObserver_.OnDeviceStatusUpdated(internalDevice, isConnected, "", "", streamInfo);
124 }
125
OnServiceStatusReceived(struct ServiceStatusListener * listener,struct ServiceStatus * serviceStatus)126 static void OnServiceStatusReceived(struct ServiceStatusListener *listener, struct ServiceStatus *serviceStatus)
127 {
128 CHECK_AND_RETURN_LOG(serviceStatus != nullptr, "Invalid ServiceStatus");
129 std::string info = serviceStatus->info;
130 AUDIO_INFO_LOG("OnServiceStatusReceived: [service name:%{public}s] [status:%{public}d]",
131 serviceStatus->serviceName, serviceStatus->status);
132
133 DeviceStatusListener *devListener = reinterpret_cast<DeviceStatusListener *>(listener->priv);
134 CHECK_AND_RETURN_LOG(devListener != nullptr, "Invalid deviceStatusListener");
135 if (serviceStatus->serviceName == AUDIO_HDI_SERVICE_NAME) {
136 if (serviceStatus->status == SERVIE_STATUS_START) {
137 devListener->deviceObserver_.OnServiceConnected(AudioServiceIndex::HDI_SERVICE_INDEX);
138 } else if (serviceStatus->status == SERVIE_STATUS_STOP) {
139 devListener->deviceObserver_.OnServiceDisconnected(AudioServiceIndex::HDI_SERVICE_INDEX);
140 } else if (serviceStatus->status == SERVIE_STATUS_CHANGE) {
141 OnDeviceStatusChange(info, devListener);
142 }
143 } else if (serviceStatus->serviceName == AUDIO_BLUETOOTH_HDI_SERVICE_NAME) {
144 #ifdef BLUETOOTH_ENABLE
145 if (serviceStatus->status == SERVIE_STATUS_START) {
146 AUDIO_INFO_LOG("Bluetooth hdi service started");
147 } else if (serviceStatus->status == SERVIE_STATUS_STOP) {
148 AUDIO_INFO_LOG("Bluetooth hdi service stopped");
149 if (Bluetooth::AudioA2dpManager::HasA2dpDeviceConnected()) {
150 AUDIO_ERR_LOG("Auto exit audio policy service for bluetooth hdi service crashed!");
151 _Exit(0);
152 }
153 }
154 #endif
155 } else if (serviceStatus->serviceName == DAUDIO_HDI_SERVICE_NAME) {
156 ReceviceDistributedInfo(serviceStatus, info, devListener);
157 } else {
158 AUDIO_DEBUG_LOG("unkown service name.");
159 }
160 }
161
DeviceStatusListener(IDeviceStatusObserver & observer)162 DeviceStatusListener::DeviceStatusListener(IDeviceStatusObserver &observer)
163 : deviceObserver_(observer), hdiServiceManager_(nullptr), listener_(nullptr) {}
164
165 DeviceStatusListener::~DeviceStatusListener() = default;
166
RegisterDeviceStatusListener()167 int32_t DeviceStatusListener::RegisterDeviceStatusListener()
168 {
169 AUDIO_INFO_LOG("Enter");
170 hdiServiceManager_ = HDIServiceManagerGet();
171 CHECK_AND_RETURN_RET_LOG(hdiServiceManager_ != nullptr, ERR_OPERATION_FAILED,
172 "[DeviceStatusListener]: Get HDI service manager failed");
173
174 listener_ = HdiServiceStatusListenerNewInstance();
175 CHECK_AND_RETURN_RET_LOG(listener_ != nullptr, ERR_ILLEGAL_STATE,
176 "[DeviceStatusListener]: status listener failed");
177 listener_->callback = OnServiceStatusReceived;
178 listener_->priv = (void *)this;
179 int32_t status = hdiServiceManager_->RegisterServiceStatusListener(hdiServiceManager_, listener_,
180 DeviceClass::DEVICE_CLASS_AUDIO);
181 CHECK_AND_RETURN_RET_LOG(status == HDF_SUCCESS, ERR_OPERATION_FAILED,
182 "[DeviceStatusListener]: Register service status listener failed");
183 AUDIO_INFO_LOG("Register service status listener finished");
184
185 #ifdef AUDIO_WIRED_DETECT
186 audioPnpServer_ = &AudioPnpServer::GetAudioPnpServer();
187 pnpDeviceCB_ = std::make_shared<AudioPnpStatusCallback>();
188 pnpDeviceCB_->SetDeviceStatusListener(this);
189 int32_t cbstatus = audioPnpServer_->RegisterPnpStatusListener(pnpDeviceCB_);
190 CHECK_AND_RETURN_RET_LOG(cbstatus == SUCCESS, ERR_OPERATION_FAILED,
191 "[DeviceStatusListener]: Register Pnp Status Listener failed");
192 #endif
193 AUDIO_INFO_LOG("Done");
194 return SUCCESS;
195 }
196
UnRegisterDeviceStatusListener()197 int32_t DeviceStatusListener::UnRegisterDeviceStatusListener()
198 {
199 if ((hdiServiceManager_ == nullptr) || (listener_ == nullptr)) {
200 return ERR_ILLEGAL_STATE;
201 }
202 int32_t status = hdiServiceManager_->UnregisterServiceStatusListener(hdiServiceManager_, listener_);
203 CHECK_AND_RETURN_RET_LOG(status == HDF_SUCCESS, ERR_OPERATION_FAILED,
204 "[DeviceStatusListener]: UnRegister service status listener failed");
205
206 hdiServiceManager_ = nullptr;
207 listener_ = nullptr;
208
209 #ifdef AUDIO_WIRED_DETECT
210 int32_t cbstatus = audioPnpServer_->UnRegisterPnpStatusListener();
211 if (cbstatus != SUCCESS) {
212 AUDIO_ERR_LOG("[DeviceStatusListener]: UnRegister Pnp Status Listener failed");
213 return ERR_OPERATION_FAILED;
214 }
215 audioPnpServer_ = nullptr;
216 pnpDeviceCB_ = nullptr;
217 #endif
218 return SUCCESS;
219 }
220
221 #ifdef AUDIO_WIRED_DETECT
OnPnpDeviceStatusChanged(const std::string & info)222 void DeviceStatusListener::OnPnpDeviceStatusChanged(const std::string &info)
223 {
224 CHECK_AND_RETURN_LOG(!info.empty(), "OnPnpDeviceStatusChange invalid info");
225
226 if (audioDeviceAnahsCb_ != nullptr) {
227 std::string anahsName = "";
228 auto anahsBegin = info.find("ANAHS_NAME=");
229 auto anahsEnd = info.find_first_of(";", anahsBegin);
230 anahsName = info.substr(anahsBegin + std::strlen("ANAHS_NAME="),
231 anahsEnd - anahsBegin - std::strlen("ANAHS_NAME="));
232 if (strncmp(anahsName.c_str(), UEVENT_INSERT, strlen(UEVENT_INSERT)) == 0 ||
233 strncmp(anahsName.c_str(), UEVENT_REMOVE, strlen(UEVENT_REMOVE)) == 0) {
234 AUDIO_INFO_LOG("parse anahsName = %{public}s", anahsName.c_str());
235 audioDeviceAnahsCb_->OnExtPnpDeviceStatusChanged(anahsName, anahsShowType_);
236 return;
237 }
238 }
239
240 PnpDeviceType pnpDeviceType = PNP_DEVICE_UNKNOWN;
241 PnpEventType pnpEventType = PNP_EVENT_UNKNOWN;
242
243 AudioDeviceDescriptor desc = {};
244
245 if (sscanf_s(info.c_str(), "EVENT_TYPE=%d;DEVICE_TYPE=%d;", &pnpEventType, &pnpDeviceType) < EVENT_NUM_TYPE) {
246 AUDIO_ERR_LOG("Failed to scan info string %{public}s", info.c_str());
247 return;
248 }
249
250 auto nameBegin = info.find("EVENT_NAME=");
251 auto nameEnd = info.find_first_of(";", nameBegin);
252 desc.deviceName_ = info.substr(nameBegin + std::strlen("EVENT_NAME="),
253 nameEnd - nameBegin - std::strlen("EVENT_NAME="));
254
255 auto addressBegin = info.find("DEVICE_ADDRESS=");
256 auto addressEnd = info.find_first_of(";", addressBegin);
257 string portId = info.substr(addressBegin + std::strlen("DEVICE_ADDRESS="),
258 addressEnd - addressBegin - std::strlen("DEVICE_ADDRESS="));
259
260 desc.deviceType_ = GetInternalDeviceType(pnpDeviceType);
261 if (desc.deviceType_ == DEVICE_TYPE_NONE) {
262 AUDIO_DEBUG_LOG("Unsupported device %{public}d", pnpDeviceType);
263 return;
264 }
265 bool isConnected = (pnpEventType == PNP_EVENT_DEVICE_ADD) ? true : false;
266
267 if (desc.deviceType_ == DEVICE_TYPE_DP) {
268 desc.macAddress_ = DP_ADDRESS + portId;
269 }
270 AUDIO_INFO_LOG("[device type: %{public}d], [connection state: %{public}d], [name: %{public}s]",
271 desc.deviceType_, isConnected, desc.deviceName_.c_str());
272 deviceObserver_.OnPnpDeviceStatusUpdated(desc, isConnected);
273 }
274 #endif
275
SetAudioDeviceAnahsCallback(const sptr<IRemoteObject> & object)276 int32_t DeviceStatusListener::SetAudioDeviceAnahsCallback(const sptr<IRemoteObject> &object)
277 {
278 sptr<IStandardAudioAnahsManagerListener> listener = iface_cast<IStandardAudioAnahsManagerListener>(object);
279 if (listener != nullptr) {
280 audioDeviceAnahsCb_ = listener;
281 return SUCCESS;
282 } else {
283 return ERROR;
284 }
285 }
286
UnsetAudioDeviceAnahsCallback()287 int32_t DeviceStatusListener::UnsetAudioDeviceAnahsCallback()
288 {
289 audioDeviceAnahsCb_ = nullptr;
290 return SUCCESS;
291 }
292
UpdateAnahsPlatformType(std::string anahsShowType)293 void DeviceStatusListener::UpdateAnahsPlatformType(std::string anahsShowType)
294 {
295 anahsShowType_ = anahsShowType;
296 }
297
OnMicrophoneBlocked(const std::string & info)298 void DeviceStatusListener::OnMicrophoneBlocked(const std::string &info)
299 {
300 CHECK_AND_RETURN_LOG(!info.empty(), "OnMicrophoneBlocked invalid info");
301
302 PnpDeviceType pnpDeviceType = PNP_DEVICE_UNKNOWN;
303 PnpEventType pnpEventType = PNP_EVENT_UNKNOWN;
304
305 if (sscanf_s(info.c_str(), "EVENT_TYPE=%d;DEVICE_TYPE=%d;", &pnpEventType, &pnpDeviceType) < EVENT_NUM_TYPE) {
306 AUDIO_ERR_LOG("Failed to scan info string %{public}s", info.c_str());
307 return;
308 }
309
310 DeviceType micBlockedDeviceType = GetInternalDeviceType(pnpDeviceType);
311 if (micBlockedDeviceType == DEVICE_TYPE_NONE) {
312 AUDIO_DEBUG_LOG("Unsupported device %{public}d", pnpDeviceType);
313 return;
314 }
315
316 DeviceBlockStatus status = DEVICE_UNBLOCKED;
317 if (pnpEventType == PNP_EVENT_MIC_BLOCKED) {
318 status = DEVICE_BLOCKED;
319 }
320 AUDIO_INFO_LOG("[device type :%{public}d], [status :%{public}d]", micBlockedDeviceType, status);
321 deviceObserver_.OnMicrophoneBlockedUpdate(micBlockedDeviceType, status);
322 }
323
324 #ifdef AUDIO_WIRED_DETECT
AudioPnpStatusCallback()325 AudioPnpStatusCallback::AudioPnpStatusCallback()
326 {
327 AUDIO_INFO_LOG("ctor");
328 }
329
~AudioPnpStatusCallback()330 AudioPnpStatusCallback::~AudioPnpStatusCallback() {}
331
SetDeviceStatusListener(DeviceStatusListener * listener)332 void AudioPnpStatusCallback::SetDeviceStatusListener(DeviceStatusListener *listener)
333 {
334 listener_ = listener;
335 }
336
OnPnpDeviceStatusChanged(const std::string & info)337 void AudioPnpStatusCallback::OnPnpDeviceStatusChanged(const std::string &info)
338 {
339 listener_->OnPnpDeviceStatusChanged(info);
340 }
341
OnMicrophoneBlocked(const std::string & info)342 void AudioPnpStatusCallback::OnMicrophoneBlocked(const std::string &info)
343 {
344 listener_->OnMicrophoneBlocked(info);
345 }
346 #endif
347 } // namespace AudioStandard
348 } // namespace OHOS
349