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