• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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