1 /*
2 * Copyright (c) 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 #ifndef HDI_DAUDIO_ATTRIBUTE_INTERNAL_H
17 #define HDI_DAUDIO_ATTRIBUTE_INTERNAL_H
18
19 #include <securec.h>
20 #include <cstdint>
21 #include <sys/mman.h>
22
23 #include "audio_types.h"
24 #include <v1_0/audio_types.h>
25
26 #include "daudio_errorcode.h"
27 #include "daudio_log.h"
28
29 #undef DH_LOG_TAG
30 #define DH_LOG_TAG "AudioAttributeInternal"
31
32 namespace OHOS {
33 namespace DistributedHardware {
34 using namespace OHOS::HDI::DistributedAudio::Audio::V1_0;
35
36 template<typename T>
37 class AudioAttributeInternal final {
38 public:
39 static int32_t GetFrameSize(AudioHandle handle, uint64_t *size);
40 static int32_t GetFrameCount(AudioHandle handle, uint64_t *count);
41 static int32_t SetSampleAttributes(AudioHandle handle, const struct ::AudioSampleAttributes *attrs);
42 static int32_t GetSampleAttributes(AudioHandle handle, struct ::AudioSampleAttributes *attrs);
43 static int32_t GetCurrentChannelId(AudioHandle handle, uint32_t *channelId);
44 static int32_t SetExtraParams(AudioHandle handle, const char *keyValueList);
45 static int32_t GetExtraParams(AudioHandle handle, char *keyValueList, int32_t listLenth);
46 static int32_t ReqMmapBuffer(AudioHandle handle, int32_t reqSize, struct ::AudioMmapBufferDescriptor *desc);
47 static int32_t GetMmapPosition(AudioHandle handle, uint64_t *frames, struct ::AudioTimeStamp *time);
48 };
49
50 template<typename T>
GetFrameSize(AudioHandle handle,uint64_t * size)51 int32_t AudioAttributeInternal<T>::GetFrameSize(AudioHandle handle, uint64_t *size)
52 {
53 if (handle == nullptr || size == nullptr) {
54 DHLOGE("The parameter is empty.");
55 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
56 }
57
58 T *context = reinterpret_cast<T *>(handle);
59 return (context == nullptr || context->proxy_ == nullptr) ?
60 ERR_DH_AUDIO_HDI_INVALID_PARAM : context->proxy_->GetFrameSize(*size);
61 }
62
63 template<typename T>
GetFrameCount(AudioHandle handle,uint64_t * count)64 int32_t AudioAttributeInternal<T>::GetFrameCount(AudioHandle handle, uint64_t *count)
65 {
66 if (handle == nullptr || count == nullptr) {
67 DHLOGE("The parameter is empty.");
68 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
69 }
70
71 T *context = reinterpret_cast<T *>(handle);
72 return (context == nullptr || context->proxy_ == nullptr) ?
73 ERR_DH_AUDIO_HDI_INVALID_PARAM : context->proxy_->GetFrameCount(*count);
74 }
75
76 template<typename T>
SetSampleAttributes(AudioHandle handle,const struct::AudioSampleAttributes * attrs)77 int32_t AudioAttributeInternal<T>::SetSampleAttributes(AudioHandle handle,
78 const struct ::AudioSampleAttributes *attrs)
79 {
80 if (handle == nullptr || attrs == nullptr) {
81 DHLOGE("The parameter is empty.");
82 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
83 }
84
85 T *context = reinterpret_cast<T *>(handle);
86 AudioSampleAttributes attrsHal = {
87 .format = static_cast<AudioFormat>(attrs->format),
88 .sampleRate = attrs->sampleRate,
89 .channelCount = attrs->channelCount,
90 };
91 DHLOGD("AttrsHal.format = %u", attrsHal.format);
92 return (context == nullptr || context->proxy_ == nullptr) ?
93 ERR_DH_AUDIO_HDI_INVALID_PARAM : context->proxy_->SetSampleAttributes(attrsHal);
94 }
95
96 template<typename T>
GetSampleAttributes(AudioHandle handle,struct::AudioSampleAttributes * attrs)97 int32_t AudioAttributeInternal<T>::GetSampleAttributes(AudioHandle handle, struct ::AudioSampleAttributes *attrs)
98 {
99 if (handle == nullptr || attrs == nullptr) {
100 DHLOGE("The parameter is empty.");
101 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
102 }
103
104 DHLOGD("Get sample attributes.");
105 T *context = reinterpret_cast<T *>(handle);
106 if (context == nullptr || context->proxy_ == nullptr) {
107 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
108 }
109
110 AudioSampleAttributes attrsHal;
111 int32_t ret = context->proxy_->GetSampleAttributes(attrsHal);
112 if (ret != DH_SUCCESS) {
113 return ret;
114 }
115
116 attrs->type = static_cast<::AudioCategory>(attrsHal.type);
117 attrs->interleaved = static_cast<bool>(attrsHal.interleaved);
118 attrs->format = static_cast<::AudioFormat>(attrsHal.format);
119 attrs->sampleRate = attrsHal.sampleRate;
120 attrs->channelCount = attrsHal.channelCount;
121 attrs->streamId = static_cast<int32_t>(attrsHal.streamId);
122 return DH_SUCCESS;
123 }
124
125 template<typename T>
GetCurrentChannelId(AudioHandle handle,uint32_t * channelId)126 int32_t AudioAttributeInternal<T>::GetCurrentChannelId(AudioHandle handle, uint32_t *channelId)
127 {
128 if (handle == nullptr || channelId == nullptr) {
129 DHLOGE("The parameter is empty.");
130 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
131 }
132
133 T *context = reinterpret_cast<T *>(handle);
134 return (context == nullptr || context->proxy_ == nullptr) ?
135 ERR_DH_AUDIO_HDI_INVALID_PARAM : context->proxy_->GetCurrentChannelId(*channelId);
136 }
137
138 template<typename T>
SetExtraParams(AudioHandle handle,const char * keyValueList)139 int32_t AudioAttributeInternal<T>::SetExtraParams(AudioHandle handle, const char *keyValueList)
140 {
141 if (handle == nullptr || keyValueList == nullptr) {
142 DHLOGE("The parameter is empty.");
143 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
144 }
145
146 T *context = reinterpret_cast<T *>(handle);
147 std::string keyValueListHal(keyValueList);
148 return (context == nullptr || context->proxy_ == nullptr) ?
149 ERR_DH_AUDIO_HDI_INVALID_PARAM : context->proxy_->SetExtraParams(keyValueListHal);
150 }
151
152 template<typename T>
GetExtraParams(AudioHandle handle,char * keyValueList,int32_t listLenth)153 int32_t AudioAttributeInternal<T>::GetExtraParams(AudioHandle handle, char *keyValueList, int32_t listLenth)
154 {
155 if (handle == nullptr || keyValueList == nullptr) {
156 DHLOGE("The parameter is empty.");
157 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
158 }
159
160 if (listLenth <= 0) {
161 DHLOGE("The parameter is invalid.");
162 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
163 }
164
165 T *context = reinterpret_cast<T *>(handle);
166 if (context == nullptr || context->proxy_ == nullptr) {
167 DHLOGE("The context is empty.");
168 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
169 }
170
171 std::string keyValueListHal(keyValueList);
172 int32_t ret = context->proxy_->GetExtraParams(keyValueListHal);
173 if (ret != DH_SUCCESS) {
174 return ret;
175 }
176 if (listLenth - 1 < (int)keyValueListHal.length()) {
177 keyValueListHal = keyValueListHal.substr(0, listLenth - 1);
178 }
179 if (strcpy_s(keyValueList, listLenth, keyValueListHal.c_str()) != EOK) {
180 DHLOGE("Strcpy_s keyValueList failed.");
181 return ERR_DH_AUDIO_HDI_CALL_FAILED;
182 }
183 return DH_SUCCESS;
184 }
185
186 template<typename T>
ReqMmapBuffer(AudioHandle handle,int32_t reqSize,struct::AudioMmapBufferDescriptor * desc)187 int32_t AudioAttributeInternal<T>::ReqMmapBuffer(AudioHandle handle, int32_t reqSize,
188 struct ::AudioMmapBufferDescriptor *desc)
189 {
190 if (handle == nullptr || desc == nullptr) {
191 DHLOGE("The parameter is empty.");
192 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
193 }
194
195 T *context = reinterpret_cast<T *>(handle);
196 if (context == nullptr || context->proxy_ == nullptr) {
197 DHLOGE("The context is empty.");
198 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
199 }
200
201 AudioMmapBufferDescriptor descHal;
202 int32_t ret = context->proxy_->ReqMmapBuffer(reqSize, descHal);
203 if (ret != DH_SUCCESS) {
204 DHLOGE("Failed to request the mmap buffer.");
205 return ret;
206 }
207
208 desc->memoryFd = descHal.memoryFd;
209 desc->totalBufferFrames = descHal.totalBufferFrames;
210 desc->transferFrameSize = descHal.transferFrameSize;
211 desc->isShareable = descHal.isShareable;
212 return DH_SUCCESS;
213 }
214
215 template<typename T>
GetMmapPosition(AudioHandle handle,uint64_t * frames,struct::AudioTimeStamp * time)216 int32_t AudioAttributeInternal<T>::GetMmapPosition(AudioHandle handle, uint64_t *frames,
217 struct ::AudioTimeStamp *time)
218 {
219 if (handle == nullptr || frames == nullptr || time == nullptr) {
220 DHLOGE("The parameter is empty.");
221 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
222 }
223 DHLOGD("Get mmap position.");
224
225 T *context = reinterpret_cast<T *>(handle);
226 if (context == nullptr || context->proxy_ == nullptr) {
227 DHLOGE("The context is empty.");
228 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
229 }
230
231 AudioTimeStamp timeHal;
232 int32_t ret = context->proxy_->GetMmapPosition(*frames, timeHal);
233 if (ret != DH_SUCCESS) {
234 DHLOGE("Failed to get the mmap position.");
235 return ret;
236 }
237
238 time->tvSec = static_cast<int64_t>(timeHal.tvSec);
239 time->tvNSec = static_cast<int64_t>(timeHal.tvNSec);
240 return DH_SUCCESS;
241 }
242 } // DistributedHardware
243 } // OHOS
244 #endif // HDI_DAUDIO_ATTRIBUTE_INTERNAL_H
245