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