• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_handler.h"
17 
18 #include <vector>
19 
20 #include "audio_system_manager.h"
21 #include "avcodec_list.h"
22 #include "string_ex.h"
23 
24 #include "daudio_constants.h"
25 #include "daudio_errorcode.h"
26 #include "daudio_log.h"
27 #include "daudio_util.h"
28 
29 #undef DH_LOG_TAG
30 #define DH_LOG_TAG "DAudioHandler"
31 
32 namespace OHOS {
33 namespace DistributedHardware {
34 IMPLEMENT_SINGLE_INSTANCE(DAudioHandler);
35 
DAudioHandler()36 DAudioHandler::DAudioHandler()
37 {
38     DHLOGD("Distributed audio handler constructed.");
39 }
40 
~DAudioHandler()41 DAudioHandler::~DAudioHandler()
42 {
43     DHLOGD("Distributed audio handler deconstructed.");
44 }
45 
Initialize()46 int32_t DAudioHandler::Initialize()
47 {
48     DHLOGI("Distributed audio handler initialize.");
49     return QueryAudioInfo();
50 }
51 
AddItemsToObject(DHItem & dhItem,cJSON * infoJson,const int32_t & dhId)52 bool DAudioHandler::AddItemsToObject(DHItem &dhItem, cJSON* infoJson, const int32_t &dhId)
53 {
54     DHLOGD("Get dhId and then add other items into cjson object");
55     int32_t deviceType = GetDevTypeByDHId(dhId);
56     if (deviceType == AUDIO_DEVICE_TYPE_MIC) {
57         return AddParamsToJson(dhItem, infoJson, MIC, micInfos_);
58     } else if (deviceType == AUDIO_DEVICE_TYPE_SPEAKER) {
59         return AddParamsToJson(dhItem, infoJson, SPEAKER, spkInfos_);
60     }
61     return true;
62 }
63 
AddParamsToJson(DHItem & dhItem,cJSON * infoJson,const std::string & subtype,const AudioInfo & infos)64 bool DAudioHandler::AddParamsToJson(DHItem &dhItem, cJSON* infoJson, const std::string &subtype, const AudioInfo &infos)
65 {
66     dhItem.subtype = subtype;
67     cJSON *sampleArray = cJSON_CreateArray();
68     CHECK_NULL_RETURN(sampleArray, false);
69     cJSON_AddItemToObject(infoJson, SAMPLERATES, sampleArray);
70     for (const auto &value : infos.sampleRates) {
71         cJSON_AddItemToArray(sampleArray, cJSON_CreateNumber(static_cast<uint32_t>(value)));
72     }
73     cJSON *channelArray = cJSON_CreateArray();
74     CHECK_NULL_RETURN(channelArray, false);
75     cJSON_AddItemToObject(infoJson, CHANNELMASKS, channelArray);
76     for (const auto &value : infos.channels) {
77         cJSON_AddItemToArray(channelArray, cJSON_CreateNumber(static_cast<uint32_t>(value)));
78     }
79     cJSON *formatsArray = cJSON_CreateArray();
80     CHECK_NULL_RETURN(formatsArray, false);
81     cJSON_AddItemToObject(infoJson, FORMATS, formatsArray);
82     for (const auto &value : infos.formats) {
83         cJSON_AddItemToArray(formatsArray, cJSON_CreateNumber(static_cast<uint32_t>(value)));
84     }
85     cJSON *usageArray = cJSON_CreateArray();
86     CHECK_NULL_RETURN(usageArray, false);
87     cJSON_AddItemToObject(infoJson, SUPPORTEDSTREAM, usageArray);
88     for (const auto &value : supportedStream_) {
89         cJSON_AddItemToArray(usageArray, cJSON_CreateString(value.c_str()));
90     }
91     cJSON *codecArray = cJSON_CreateArray();
92     CHECK_NULL_RETURN(codecArray, false);
93     cJSON_AddItemToObject(infoJson, CODEC, codecArray);
94     for (const auto &value : codec_) {
95         cJSON_AddItemToArray(codecArray, cJSON_CreateString(value.c_str()));
96     }
97     cJSON_AddStringToObject(infoJson, PROTOCOLVER, VERSION_TWO);
98     return true;
99 }
100 
QueryMeta()101 std::vector<DHItem> DAudioHandler::QueryMeta()
102 {
103     DHLOGI("Query meta distributed hardware information.");
104     return RealQuery(KEY_TYPE_META);
105 }
106 
Query()107 std::vector<DHItem> DAudioHandler::Query()
108 {
109     DHLOGI("Query full distributed hardware information.");
110     return RealQuery(KEY_TYPE_FULL);
111 }
112 
RealQuery(const std::string & dataType)113 std::vector<DHItem> DAudioHandler::RealQuery(const std::string &dataType)
114 {
115     auto audioSrv = AudioStandard::AudioSystemManager::GetInstance();
116     std::vector<DHItem> dhItemVec;
117     CHECK_AND_RETURN_RET_LOG(audioSrv == nullptr, dhItemVec, "Unable to get audio system manager.");
118     auto audioDevices = audioSrv->GetDevices(AudioStandard::DeviceFlag::ALL_DEVICES_FLAG);
119     for (auto dev : audioDevices) {
120         if (dev == nullptr) {
121             continue;
122         }
123         auto dhId = audioSrv->GetPinValueFromType(dev->deviceType_, dev->deviceRole_);
124         if (dhId != DEFAULT_RENDER_ID && dhId != DEFAULT_CAPTURE_ID) {
125             continue;
126         }
127 
128         cJSON* infoJson = cJSON_CreateObject();
129         if (infoJson == nullptr) {
130             DHLOGE("Failed to create cJSON object.");
131             return dhItemVec;
132         }
133         DHItem dhItem;
134         if (!AddItemsToObject(dhItem, infoJson, dhId)) {
135             cJSON_Delete(infoJson);
136             return dhItemVec;
137         }
138         cJSON_AddNumberToObject(infoJson, INTERRUPT_GROUP_ID, dev->interruptGroupId_);
139         cJSON_AddNumberToObject(infoJson, VOLUME_GROUP_ID, dev->volumeGroupId_);
140         cJSON_AddStringToObject(infoJson, KEY_DATATYPE, dataType.c_str());
141         dhItem.dhId = std::to_string(dhId);
142         char *jsonInfo = cJSON_Print(infoJson);
143         if (jsonInfo == NULL) {
144             DHLOGE("Failed to create JSON data.");
145             cJSON_Delete(infoJson);
146             return dhItemVec;
147         }
148         dhItem.attrs = jsonInfo;
149         dhItemVec.push_back(dhItem);
150         DHLOGD("Query result: dhId: %{public}d, subtype: %{public}s, attrs: %{public}s.",
151             dhId, dhItem.subtype.c_str(), jsonInfo);
152         if (dhId == DEFAULT_RENDER_ID) {
153             dhItem.dhId = std::to_string(LOW_LATENCY_RENDER_ID);
154             dhItemVec.push_back(dhItem);
155             DHLOGD("Query result: dhId: %{public}d, attrs: %{public}s.", LOW_LATENCY_RENDER_ID, jsonInfo);
156         }
157         cJSON_Delete(infoJson);
158         cJSON_free(jsonInfo);
159     }
160     DHLOGD("Query result: size: (%{public}zu).", dhItemVec.size());
161     ablityForDumpVec_ = dhItemVec;
162     return dhItemVec;
163 }
164 
ablityForDump()165 std::vector<DHItem> DAudioHandler::ablityForDump()
166 {
167     DHLOGD("Get audio ablity for dump.");
168     if (ablityForDumpVec_.size() > 0) {
169         return ablityForDumpVec_;
170     }
171     Initialize();
172     Query();
173     return ablityForDumpVec_;
174 }
175 
IsMimeSupported(const std::string & coder)176 bool DAudioHandler::IsMimeSupported(const std::string &coder)
177 {
178     DHLOGD("Craete avCodecList start.");
179     std::shared_ptr<MediaAVCodec::AVCodecList> avCodecList = MediaAVCodec::AVCodecListFactory::CreateAVCodecList();
180     if (avCodecList == nullptr) {
181         DHLOGE("Create avCodecList failed.");
182         return false;
183     }
184     MediaAVCodec::CapabilityData *capData = avCodecList->GetCapability(coder, true,
185         MediaAVCodec::AVCodecCategory::AVCODEC_NONE);
186     if (capData == nullptr) {
187         DHLOGI("%{public}s is not supported.", coder.c_str());
188         return false;
189     }
190     return true;
191 }
192 
AddToVec(std::vector<std::string> & container,const std::string & value)193 void DAudioHandler::AddToVec(std::vector<std::string> &container, const std::string &value)
194 {
195     auto it = std::find(container.begin(), container.end(), value);
196     if (it == container.end()) {
197         container.push_back(value);
198     }
199 }
200 
QueryAudioInfo()201 int32_t DAudioHandler::QueryAudioInfo()
202 {
203     DHLOGD("Start to query codec information.");
204     micInfos_.sampleRates = OHOS::AudioStandard::AudioCapturer::GetSupportedSamplingRates();
205     micInfos_.formats = OHOS::AudioStandard::AudioCapturer::GetSupportedFormats();
206     micInfos_.channels = OHOS::AudioStandard::AudioCapturer::GetSupportedChannels();
207     spkInfos_.sampleRates = OHOS::AudioStandard::AudioRenderer::GetSupportedSamplingRates();
208     spkInfos_.formats = OHOS::AudioStandard::AudioRenderer::GetSupportedFormats();
209     spkInfos_.channels = OHOS::AudioStandard::AudioRenderer::GetSupportedChannels();
210     AddToVec(supportedStream_, MUSIC);
211     AddToVec(codec_, PCM);
212     if (IsMimeSupported(std::string(MediaAVCodec::CodecMimeType::AUDIO_AAC))) {
213         AddToVec(codec_, AAC);
214     }
215     if (IsMimeSupported(std::string(MediaAVCodec::CodecMimeType::AUDIO_OPUS))) {
216         AddToVec(codec_, OPUS);
217     }
218     return DH_SUCCESS;
219 }
220 
QueryExtraInfo()221 std::map<std::string, std::string> DAudioHandler::QueryExtraInfo()
222 {
223     DHLOGD("Query extra information");
224     std::map<std::string, std::string> extraInfo;
225     return extraInfo;
226 }
227 
IsSupportPlugin()228 bool DAudioHandler::IsSupportPlugin()
229 {
230     DHLOGD("Is support plug in");
231     return false;
232 }
233 
RegisterPluginListener(std::shared_ptr<PluginListener> listener)234 void DAudioHandler::RegisterPluginListener(std::shared_ptr<PluginListener> listener)
235 {
236     DHLOGI("Register plugin listener");
237     CHECK_NULL_VOID(listener);
238     listener_ = listener;
239 }
240 
UnRegisterPluginListener()241 void DAudioHandler::UnRegisterPluginListener()
242 {
243     DHLOGI("UnRegister plugin listener");
244     listener_ = nullptr;
245 }
246 
GetHardwareHandler()247 IHardwareHandler* GetHardwareHandler()
248 {
249     return &DAudioHandler::GetInstance();
250 }
251 } // namespace DistributedHardware
252 } // namespace OHOS
253