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