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