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
16 #include "device_status_listener.h"
17
18 #include <securec.h>
19
20 #include "hdf_device_class.h"
21 #include "v1_0/audio_types.h"
22 #ifdef BLUETOOTH_ENABLE
23 #include "audio_bluetooth_manager.h"
24 #include "bluetooth_def.h"
25 #endif
26
27 #include "audio_errors.h"
28 #include "audio_log.h"
29
30 namespace OHOS {
31 namespace AudioStandard {
32 const std::string AUDIO_HDI_SERVICE_NAME = "audio_manager_service";
33 const std::string AUDIO_HDI_PNP_SERVICE_NAME = "audio_hdi_pnp_service";
34 const std::string AUDIO_BLUETOOTH_HDI_SERVICE_NAME = "audio_bluetooth_hdi_service";
35
36 const std::string DAUDIO_HDI_SERVICE_NAME = "daudio_primary_service";
37 const uint8_t EVENT_PARAMS = 2;
38 const uint8_t D_EVENT_PARAMS = 5;
39
GetInternalDeviceType(AudioDeviceType hdiDeviceType)40 static DeviceType GetInternalDeviceType(AudioDeviceType hdiDeviceType)
41 {
42 DeviceType internalDeviceType = DEVICE_TYPE_NONE;
43
44 switch (hdiDeviceType) {
45 case AudioDeviceType::AUDIO_HEADSET:
46 internalDeviceType = DEVICE_TYPE_WIRED_HEADSET;
47 break;
48 case AudioDeviceType::AUDIO_HEADPHONE:
49 internalDeviceType = DEVICE_TYPE_WIRED_HEADPHONES;
50 break;
51 case AudioDeviceType::AUDIO_USB_HEADSET:
52 internalDeviceType = DEVICE_TYPE_USB_HEADSET;
53 break;
54 case AudioDeviceType::AUDIO_ADAPTER_DEVICE:
55 internalDeviceType = DEVICE_TYPE_EXTERN_CABLE;
56 break;
57 default:
58 internalDeviceType = DEVICE_TYPE_NONE;
59 break;
60 }
61
62 return internalDeviceType;
63 }
64
ReceviceDistributedInfo(struct ServiceStatus * serviceStatus,std::string & info,DeviceStatusListener * devListener)65 static void ReceviceDistributedInfo(struct ServiceStatus* serviceStatus, std::string & info,
66 DeviceStatusListener * devListener)
67 {
68 if (serviceStatus->status == SERVIE_STATUS_START) {
69 AUDIO_DEBUG_LOG("distributed service online");
70 } else if (serviceStatus->status == SERVIE_STATUS_CHANGE && !info.empty()) {
71 DStatusInfo statusInfo;
72 statusInfo.connectType = ConnectType::CONNECT_TYPE_DISTRIBUTED;
73 AudioEventType hdiEventType = AUDIO_EVENT_UNKNOWN;
74 if (sscanf_s(info.c_str(), "EVENT_TYPE=%d;NID=%[^;];PIN=%d;VID=%d;IID=%d", &hdiEventType,
75 statusInfo.networkId, sizeof(statusInfo.networkId), &(statusInfo.hdiPin), &(statusInfo.mappingVolumeId),
76 &(statusInfo.mappingInterruptId)) < D_EVENT_PARAMS) {
77 AUDIO_ERR_LOG("[DeviceStatusListener]: Failed to scan info string");
78 return;
79 }
80
81 statusInfo.isConnected = (hdiEventType == AUDIO_DEVICE_ADD) ? true : false;
82 devListener->deviceObserver_.OnDeviceStatusUpdated(statusInfo);
83 }
84 }
85
OnDeviceStatusChange(const std::string & info,DeviceStatusListener * devListener)86 static void OnDeviceStatusChange(const std::string &info, DeviceStatusListener *devListener)
87 {
88 CHECK_AND_RETURN_LOG(!info.empty(), "OnDeviceStatusChange invalid info");
89 AudioDeviceType hdiDeviceType = AUDIO_DEVICE_UNKNOWN;
90 AudioEventType hdiEventType = AUDIO_EVENT_UNKNOWN;
91 if (sscanf_s(info.c_str(), "EVENT_TYPE=%d;DEVICE_TYPE=%d", &hdiEventType, &hdiDeviceType) < EVENT_PARAMS) {
92 AUDIO_WARNING_LOG("[DeviceStatusListener]: Failed to scan info string %{public}s", info.c_str());
93 return;
94 }
95
96 DeviceType internalDevice = GetInternalDeviceType(hdiDeviceType);
97 CHECK_AND_RETURN_LOG(internalDevice != DEVICE_TYPE_NONE, "Unsupported device %{public}d", hdiDeviceType);
98
99 bool isConnected = (hdiEventType == AUDIO_DEVICE_ADD) ? true : false;
100 AudioStreamInfo streamInfo = {};
101 devListener->deviceObserver_.OnDeviceStatusUpdated(internalDevice, isConnected, "", "", streamInfo);
102 }
103
OnPnpDeviceStatusChange(const std::string & info,DeviceStatusListener * devListener)104 static void OnPnpDeviceStatusChange(const std::string &info, DeviceStatusListener *devListener)
105 {
106 CHECK_AND_RETURN_LOG(!info.empty(), "OnPnpDeviceStatusChange invalid info");
107 AudioDeviceType hdiDeviceType = AUDIO_DEVICE_UNKNOWN;
108 AudioEventType hdiEventType = AUDIO_EVENT_UNKNOWN;
109 if (sscanf_s(info.c_str(), "EVENT_TYPE=%d;DEVICE_TYPE=%d", &hdiEventType, &hdiDeviceType) < EVENT_PARAMS) {
110 AUDIO_WARNING_LOG("[DeviceStatusListener]: Failed to scan info string %{public}s", info.c_str());
111 return;
112 }
113
114 DeviceType internalDevice = GetInternalDeviceType(hdiDeviceType);
115 CHECK_AND_RETURN_LOG(internalDevice != DEVICE_TYPE_NONE, "Unsupported device %{public}d", hdiDeviceType);
116
117 bool isConnected = (hdiEventType == AUDIO_DEVICE_ADD) ? true : false;
118 devListener->deviceObserver_.OnPnpDeviceStatusUpdated(internalDevice, isConnected);
119 }
120
OnServiceStatusReceived(struct ServiceStatusListener * listener,struct ServiceStatus * serviceStatus)121 static void OnServiceStatusReceived(struct ServiceStatusListener *listener, struct ServiceStatus *serviceStatus)
122 {
123 CHECK_AND_RETURN_LOG(serviceStatus != nullptr, "Invalid ServiceStatus");
124 std::string info = serviceStatus->info;
125 AUDIO_INFO_LOG("OnServiceStatusReceived: [service name:%{public}s] [status:%{public}d] [info:%{public}s]",
126 serviceStatus->serviceName, serviceStatus->status, info.c_str());
127
128 DeviceStatusListener *devListener = reinterpret_cast<DeviceStatusListener *>(listener->priv);
129 CHECK_AND_RETURN_LOG(devListener != nullptr, "Invalid deviceStatusListener");
130 if (serviceStatus->serviceName == AUDIO_HDI_SERVICE_NAME) {
131 if (serviceStatus->status == SERVIE_STATUS_START) {
132 devListener->deviceObserver_.OnServiceConnected(AudioServiceIndex::HDI_SERVICE_INDEX);
133 } else if (serviceStatus->status == SERVIE_STATUS_STOP) {
134 devListener->deviceObserver_.OnServiceDisconnected(AudioServiceIndex::HDI_SERVICE_INDEX);
135 } else if (serviceStatus->status == SERVIE_STATUS_CHANGE) {
136 OnDeviceStatusChange(info, devListener);
137 }
138 } else if (serviceStatus->serviceName == AUDIO_HDI_PNP_SERVICE_NAME) {
139 if (serviceStatus->status == SERVIE_STATUS_CHANGE || serviceStatus->status == SERVIE_STATUS_START) {
140 OnPnpDeviceStatusChange(info, devListener);
141 }
142 } else if (serviceStatus->serviceName == AUDIO_BLUETOOTH_HDI_SERVICE_NAME) {
143 #ifdef BLUETOOTH_ENABLE
144 if (serviceStatus->status == SERVIE_STATUS_START) {
145 AUDIO_INFO_LOG("Bluetooth hdi service started");
146 Bluetooth::AudioA2dpManager::ConnectBluetoothA2dpSink();
147 } else if (serviceStatus->status == SERVIE_STATUS_STOP) {
148 AUDIO_INFO_LOG("Bluetooth hdi service stopped");
149 if (Bluetooth::AudioA2dpManager::GetConnectionState() ==
150 static_cast<int>(Bluetooth::BTConnectState::CONNECTED)) {
151 AUDIO_ERR_LOG("Auto exit audio policy service for bluetooth hdi service crashed!");
152 _Exit(0);
153 }
154 }
155 #endif
156 } else if (serviceStatus->serviceName == DAUDIO_HDI_SERVICE_NAME) {
157 ReceviceDistributedInfo(serviceStatus, info, devListener);
158 } else {
159 AUDIO_DEBUG_LOG("unkown service name.");
160 }
161 }
162
DeviceStatusListener(IDeviceStatusObserver & observer)163 DeviceStatusListener::DeviceStatusListener(IDeviceStatusObserver &observer)
164 : deviceObserver_(observer), hdiServiceManager_(nullptr), listener_(nullptr) {}
165
166 DeviceStatusListener::~DeviceStatusListener() = default;
167
RegisterDeviceStatusListener()168 int32_t DeviceStatusListener::RegisterDeviceStatusListener()
169 {
170 hdiServiceManager_ = HDIServiceManagerGet();
171 if (hdiServiceManager_ == nullptr) {
172 AUDIO_ERR_LOG("[DeviceStatusListener]: Get HDI service manager failed");
173 return ERR_OPERATION_FAILED;
174 }
175
176 listener_ = HdiServiceStatusListenerNewInstance();
177 listener_->callback = OnServiceStatusReceived;
178 listener_->priv = (void *)this;
179 int32_t status = hdiServiceManager_->RegisterServiceStatusListener(hdiServiceManager_, listener_,
180 DeviceClass::DEVICE_CLASS_AUDIO);
181 if (status != HDF_SUCCESS) {
182 AUDIO_ERR_LOG("[DeviceStatusListener]: Register service status listener failed");
183 return ERR_OPERATION_FAILED;
184 }
185
186 return SUCCESS;
187 }
188
UnRegisterDeviceStatusListener()189 int32_t DeviceStatusListener::UnRegisterDeviceStatusListener()
190 {
191 if ((hdiServiceManager_ == nullptr) || (listener_ == nullptr)) {
192 return ERR_ILLEGAL_STATE;
193 }
194
195 int32_t status = hdiServiceManager_->UnregisterServiceStatusListener(hdiServiceManager_, listener_);
196 if (status != HDF_SUCCESS) {
197 AUDIO_ERR_LOG("[DeviceStatusListener]: UnRegister service status listener failed");
198 return ERR_OPERATION_FAILED;
199 }
200
201 hdiServiceManager_ = nullptr;
202 listener_ = nullptr;
203
204 return SUCCESS;
205 }
206 } // namespace AudioStandard
207 } // namespace OHOS
208