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