1 /*
2 * Copyright (c) 2022-2025 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 "daudio_manager_callback.h"
17
18 #include <string>
19 #include <hdf_base.h>
20 #include <cstdlib>
21 #include "iservice_registry.h"
22 #include "iservmgr_hdi.h"
23 #include "iproxy_broker.h"
24
25 #include "daudio_constants.h"
26 #include "daudio_errorcode.h"
27 #include "daudio_hdi_handler.h"
28 #include "daudio_hitrace.h"
29 #include "daudio_log.h"
30 #include "daudio_radar.h"
31 #include "daudio_util.h"
32
33 #undef DH_LOG_TAG
34 #define DH_LOG_TAG "DAudioHdiHandler"
35
36 namespace OHOS {
37 namespace DistributedHardware {
38 IMPLEMENT_SINGLE_INSTANCE(DAudioHdiHandler);
39
DAudioHdiHandler()40 DAudioHdiHandler::DAudioHdiHandler()
41 {
42 DHLOGD("Distributed audio hdi handler construct.");
43 audioHdiRecipient_ = sptr<AudioHdiRecipient>(new AudioHdiRecipient());
44 }
45
~DAudioHdiHandler()46 DAudioHdiHandler::~DAudioHdiHandler()
47 {
48 DHLOGD("Distributed audio hdi handler deconstructed.");
49 }
50
InitHdiHandler()51 int32_t DAudioHdiHandler::InitHdiHandler()
52 {
53 DHLOGI("Init hdi handler.");
54 if (audioSrvHdf_ != nullptr) {
55 return DH_SUCCESS;
56 }
57
58 DHLOGD("Load hdf driver start.");
59 auto dHFwkKit = GetDHFwkKit();
60 CHECK_NULL_RETURN(dHFwkKit, ERR_DH_AUDIO_NULLPTR);
61 int32_t ret = dHFwkKit->LoadDistributedHDF(DHType::AUDIO);
62 DaudioRadar::GetInstance().ReportDaudioInit("LoadDaudioHDFImpl", AudioInit::LOAD_HDF_DRIVER,
63 BizState::BIZ_STATE_END, ret);
64 if (ret != DH_SUCCESS) {
65 DHLOGE("Load hdf driver failed, ret: %{public}d", ret);
66 return ret;
67 }
68 DHLOGI("Load hdf driver end.");
69
70 audioSrvHdf_ = IDAudioManager::Get(HDF_AUDIO_SERVICE_NAME.c_str(), false);
71 CHECK_NULL_RETURN(audioSrvHdf_, ERR_DH_AUDIO_NULLPTR);
72 remote_ = OHOS::HDI::hdi_objcast<IDAudioManager>(audioSrvHdf_);
73 CHECK_NULL_RETURN(remote_, ERR_DH_AUDIO_NULLPTR);
74 remote_->AddDeathRecipient(audioHdiRecipient_);
75 DHLOGD("Init hdi handler success.");
76 return DH_SUCCESS;
77 }
78
UninitHdiHandler()79 int32_t DAudioHdiHandler::UninitHdiHandler()
80 {
81 DHLOGI("Unload hdf driver start.");
82 CHECK_NULL_RETURN(remote_, ERR_DH_AUDIO_NULLPTR);
83 remote_->RemoveDeathRecipient(audioHdiRecipient_);
84 CHECK_NULL_RETURN(audioSrvHdf_, DH_SUCCESS);
85
86 auto dHFwkKit = GetDHFwkKit();
87 CHECK_NULL_RETURN(dHFwkKit, ERR_DH_AUDIO_NULLPTR);
88 int32_t ret = dHFwkKit->UnLoadDistributedHDF(DHType::AUDIO);
89 if (ret != DH_SUCCESS) {
90 DHLOGE("Unload hdf driver failed, ret: %{public}d", ret);
91 return ret;
92 }
93 DHLOGD("Uninit hdi handler success.");
94 return DH_SUCCESS;
95 }
96
RegisterAudioDevice(const std::string & devId,const int32_t dhId,const std::string & capability,const std::shared_ptr<IDAudioHdiCallback> & callbackObjParam)97 int32_t DAudioHdiHandler::RegisterAudioDevice(const std::string &devId, const int32_t dhId,
98 const std::string &capability, const std::shared_ptr<IDAudioHdiCallback> &callbackObjParam)
99 {
100 DHLOGI("Register audio device, adpname: %{public}s, dhId: %{public}d", GetAnonyString(devId).c_str(), dhId);
101 CHECK_NULL_RETURN(audioSrvHdf_, ERR_DH_AUDIO_NULLPTR);
102 std::string searchKey;
103 switch (GetDevTypeByDHId(dhId)) {
104 case AUDIO_DEVICE_TYPE_SPEAKER:
105 searchKey = devId + "Speaker" + std::to_string(dhId);
106 break;
107 case AUDIO_DEVICE_TYPE_MIC:
108 searchKey = devId + "Mic" + std::to_string(dhId);
109 break;
110 case AUDIO_DEVICE_TYPE_UNKNOWN:
111 default:
112 DHLOGE("Unknown audio device.");
113 return ERR_DH_AUDIO_NOT_SUPPORT;
114 }
115 {
116 std::lock_guard<std::mutex> devLck(devMapMtx_);
117 auto call = mapAudioMgrCallback_.find(searchKey);
118 if (call == mapAudioMgrCallback_.end()) {
119 const sptr<DAudioManagerCallback> callbackptr(new DAudioManagerCallback(callbackObjParam));
120 mapAudioMgrCallback_.emplace(searchKey, callbackptr);
121 }
122 auto dhIds = mapAudioMgrDhIds_.find(devId);
123 if (dhIds != mapAudioMgrDhIds_.end()) {
124 dhIds->second.insert(dhId);
125 } else {
126 std::set<int32_t> newDhIds;
127 newDhIds.insert(dhId);
128 mapAudioMgrDhIds_.emplace(devId, newDhIds);
129 }
130 }
131
132 auto iter = mapAudioMgrCallback_.find(searchKey);
133 if (iter != mapAudioMgrCallback_.end()) {
134 int32_t res = audioSrvHdf_->RegisterAudioDevice(devId, dhId, capability, iter->second);
135 if (res != HDF_SUCCESS) {
136 DHLOGE("Call hdf proxy register failed, res: %{public}d", res);
137 return ERR_DH_AUDIO_HDI_CALL_FAILED;
138 }
139 }
140 return DH_SUCCESS;
141 }
142
UnRegisterAudioDevice(const std::string & devId,const int32_t dhId)143 int32_t DAudioHdiHandler::UnRegisterAudioDevice(const std::string &devId, const int32_t dhId)
144 {
145 DHLOGI("Unregister audio device, adpname: %{public}s, dhId: %{public}d", GetAnonyString(devId).c_str(), dhId);
146 CHECK_NULL_RETURN(audioSrvHdf_, ERR_DH_AUDIO_NULLPTR);
147 int32_t res = audioSrvHdf_->UnRegisterAudioDevice(devId, dhId);
148 DaudioRadar::GetInstance().ReportDaudioUnInitProgress("UnRegisterAudioDevice",
149 AudioUnInit::UNLOAD_HDF_DRIVER, res);
150 if (res != HDF_SUCCESS) {
151 DHLOGE("Call hdf proxy unregister failed, res: %{public}d", res);
152 return ERR_DH_AUDIO_HDI_CALL_FAILED;
153 }
154
155 {
156 std::lock_guard<std::mutex> devLck(devMapMtx_);
157 auto iter = mapAudioMgrDhIds_.find(devId);
158 if (iter == mapAudioMgrDhIds_.end()) {
159 DHLOGE("Can not find register devId. devId: %{public}s", GetAnonyString(devId).c_str());
160 return ERR_DH_AUDIO_SA_UNREGISTERCALLBACK_NOT_FOUND;
161 }
162
163 iter->second.erase(dhId);
164 if (iter->second.empty()) {
165 mapAudioMgrDhIds_.erase(devId);
166 }
167 }
168 return DH_SUCCESS;
169 }
170
ProcessEventMsg(const AudioEvent & audioEvent,DAudioEvent & newEvent)171 void DAudioHdiHandler::ProcessEventMsg(const AudioEvent &audioEvent, DAudioEvent &newEvent)
172 {
173 switch (audioEvent.type) {
174 case AudioEventType::NOTIFY_OPEN_SPEAKER_RESULT:
175 newEvent.type = AUDIO_EVENT_OPEN_SPK_RESULT;
176 break;
177 case AudioEventType::NOTIFY_CLOSE_SPEAKER_RESULT:
178 newEvent.type = AUDIO_EVENT_CLOSE_SPK_RESULT;
179 break;
180 case AudioEventType::NOTIFY_OPEN_MIC_RESULT:
181 newEvent.type = AUDIO_EVENT_OPEN_MIC_RESULT;
182 break;
183 case AudioEventType::NOTIFY_CLOSE_MIC_RESULT:
184 newEvent.type = AUDIO_EVENT_CLOSE_MIC_RESULT;
185 break;
186 case AudioEventType::VOLUME_CHANGE:
187 newEvent.type = AUDIO_EVENT_VOLUME_CHANGE;
188 break;
189 case AudioEventType::SPEAKER_CLOSED:
190 newEvent.type = AUDIO_EVENT_SPK_CLOSED;
191 break;
192 case AudioEventType::MIC_CLOSED:
193 newEvent.type = AUDIO_EVENT_MIC_CLOSED;
194 break;
195 case AudioEventType::AUDIO_FOCUS_CHANGE:
196 newEvent.type = AUDIO_EVENT_FOCUS_CHANGE;
197 break;
198 case AudioEventType::AUDIO_RENDER_STATE_CHANGE:
199 newEvent.type = AUDIO_EVENT_RENDER_STATE_CHANGE;
200 break;
201 case AudioEventType::NOTIFY_HDF_SPK_DUMP:
202 newEvent.type = AUDIO_EVENT_SPK_DUMP;
203 break;
204 case AudioEventType::NOTIFY_HDF_MIC_DUMP:
205 newEvent.type = AUDIO_EVENT_MIC_DUMP;
206 break;
207 default:
208 DHLOGE("Unsupport audio event.");
209 break;
210 }
211 }
212
NotifyEvent(const std::string & devId,const int32_t dhId,const int32_t streamId,const AudioEvent & audioEvent)213 int32_t DAudioHdiHandler::NotifyEvent(const std::string &devId, const int32_t dhId,
214 const int32_t streamId, const AudioEvent &audioEvent)
215 {
216 DHLOGD("Notify event adpname: %{public}s, dhId: %{public}d, event type: %{public}d, event content: %{public}s.",
217 GetAnonyString(devId).c_str(), dhId, audioEvent.type, audioEvent.content.c_str());
218 DAudioEvent newEvent = {AUDIO_EVENT_UNKNOWN, audioEvent.content};
219 ProcessEventMsg(audioEvent, newEvent);
220
221 CHECK_NULL_RETURN(audioSrvHdf_, ERR_DH_AUDIO_NULLPTR);
222 if (audioSrvHdf_->NotifyEvent(devId, dhId, streamId, newEvent) != HDF_SUCCESS) {
223 DHLOGE("Call hdf proxy NotifyEvent failed.");
224 return ERR_DH_AUDIO_HDI_CALL_FAILED;
225 }
226 return DH_SUCCESS;
227 }
228
GetDHFwkKit()229 std::shared_ptr<DistributedHardwareFwkKit> DAudioHdiHandler::GetDHFwkKit()
230 {
231 if (dHFwkKit_ == nullptr) {
232 std::lock_guard<std::mutex> lock(dHFwkKitMutex_);
233 if (dHFwkKit_ == nullptr) {
234 dHFwkKit_ = std::make_shared<DistributedHardwareFwkKit>();
235 }
236 }
237 return dHFwkKit_;
238 }
239
OnRemoteDied(const wptr<IRemoteObject> & remote)240 void DAudioHdiHandler::AudioHdiRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
241 {
242 DHLOGE("Exit the current process remote died.");
243 _Exit(0);
244 }
245 } // namespace DistributedHardware
246 } // namespace OHOS
247