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