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#include "daudio_hidumper.h"
17
18#include "daudio_constants.h"
19#include "daudio_errorcode.h"
20#include "daudio_log.h"
21#include "daudio_util.h"
22
23#undef DH_LOG_TAG
24#define DH_LOG_TAG "DaudioHidumper"
25
26namespace OHOS {
27namespace DistributedHardware {
28IMPLEMENT_SINGLE_INSTANCE(DaudioHidumper);
29
30namespace {
31const std::string ARGS_HELP = "-h";
32const std::string ARGS_SOURCE_DEVID = "--sourceDevId";
33const std::string ARGS_SINK_INFO = "--sinkInfo";
34const std::string ARGS_ABILITY = "--ability";
35const std::string ARGS_DUMP_AUDIO_DATA_START = "--startDump";
36const std::string ARGS_DUMP_AUDIO_DATA_STOP = "--stopDump";
37
38const std::map<std::string, HidumpFlag> ARGS_MAP = {
39    { ARGS_HELP, HidumpFlag::GET_HELP },
40    { ARGS_SOURCE_DEVID, HidumpFlag::GET_SOURCE_DEVID },
41    { ARGS_SINK_INFO, HidumpFlag::GET_SINK_INFO },
42    { ARGS_ABILITY, HidumpFlag::GET_ABILITY },
43    { ARGS_DUMP_AUDIO_DATA_START, HidumpFlag::DUMP_AUDIO_DATA_START },
44    { ARGS_DUMP_AUDIO_DATA_STOP, HidumpFlag::DUMP_AUDIO_DATA_STOP },
45};
46}
47
48DaudioHidumper::DaudioHidumper()
49{
50    DHLOGI("Distributed audio hidumper constructed.");
51}
52
53DaudioHidumper::~DaudioHidumper()
54{
55    DHLOGI("Distributed audio hidumper deconstructed.");
56}
57
58bool DaudioHidumper::Dump(const std::vector<std::string> &args, std::string &result)
59{
60    result.clear();
61    int32_t argsSize = static_cast<int32_t>(args.size());
62    DHLOGI("Distributed audio hidumper dump args.size():%{public}d", argsSize);
63    for (int32_t i = 0; i < argsSize; i++) {
64        DHLOGD("Distributed audio hidumper dump args[%{public}d]: %{public}s.", i, args.at(i).c_str());
65    }
66
67    if (args.empty()) {
68        ShowHelp(result);
69        return true;
70    } else if (args.size() > 1) {
71        ShowIllegalInfomation(result);
72        return true;
73    }
74
75    return ProcessDump(args[0], result) == DH_SUCCESS;
76}
77
78int32_t DaudioHidumper::ProcessDump(const std::string &args, std::string &result)
79{
80    DHLOGI("Process dump.");
81    HidumpFlag hf = HidumpFlag::UNKNOWN;
82    auto operatorIter = ARGS_MAP.find(args);
83    if (operatorIter != ARGS_MAP.end()) {
84        hf = operatorIter->second;
85    }
86
87    if (hf == HidumpFlag::GET_HELP) {
88        ShowHelp(result);
89        return DH_SUCCESS;
90    }
91    result.clear();
92    switch (hf) {
93        case HidumpFlag::GET_SOURCE_DEVID: {
94            return GetSourceDevId(result);
95        }
96        case HidumpFlag::GET_SINK_INFO: {
97            return GetSinkInfo(result);
98        }
99        case HidumpFlag::GET_ABILITY: {
100            return GetAbilityInfo(result);
101        }
102        case HidumpFlag::DUMP_AUDIO_DATA_START: {
103            return StartDumpData(result);
104        }
105        case HidumpFlag::DUMP_AUDIO_DATA_STOP: {
106            return StopDumpData(result);
107        }
108        default: {
109            return ShowIllegalInfomation(result);
110        }
111    }
112}
113
114int32_t DaudioHidumper::GetSourceDevId(std::string &result)
115{
116    DHLOGI("Get source devId dump.");
117    std::string sourceDevId = "";
118    int32_t ret = GetLocalDeviceNetworkId(sourceDevId);
119    if (ret != DH_SUCCESS) {
120        DHLOGE("Get local network id failed.");
121        result.append("sourceDevId: ").append("");
122        return ret;
123    }
124    result.append("sourceDevId: ").append(GetAnonyString(sourceDevId));
125    return DH_SUCCESS;
126}
127
128int32_t DaudioHidumper::GetSinkInfo(std::string &result)
129{
130    DHLOGI("Get sink info dump.");
131
132    audioManager_ = IAudioManager::Get("daudio_primary_service", false);
133    if (audioManager_ == nullptr) {
134        return ERR_DH_AUDIO_NULLPTR;
135    }
136    int32_t ret = audioManager_->GetAllAdapters(adapterdesc_);
137    if (ret != DH_SUCCESS) {
138        DHLOGE("Get all adapters failed.");
139        return ERR_DH_AUDIO_NULLPTR;
140    }
141    for (uint32_t index = 0; index < adapterdesc_.size(); index++) {
142        AudioAdapterDescriptor desc = adapterdesc_[index];
143        result.append("sinkDevId: ").append(GetAnonyString(desc.adapterName)).append("    portId: ");
144        for (uint32_t i = 0; i < desc.ports.size(); i++) {
145            result.append(std::to_string(desc.ports[i].portId)).append(" ");
146        }
147    }
148
149    return DH_SUCCESS;
150}
151
152int32_t DaudioHidumper::GetAbilityInfo(std::string &result)
153{
154    DHLOGI("Obtaining capability information.");
155    std::vector<DHItem> abilityInfo = DAudioHandler::GetInstance().ablityForDump();
156    for (DHItem dhItem : abilityInfo) {
157        if (dhItem.dhId == DEFAULT_SPK_DHID) {
158            result.append("spkAbilityInfo:").append(dhItem.attrs).append("      ");
159        }
160        if (dhItem.dhId == DEFAULT_MIC_DHID) {
161            result.append("micAbilityInfo:").append(dhItem.attrs).append("      ");
162        }
163    }
164    return DH_SUCCESS;
165}
166
167int32_t DaudioHidumper::StartDumpData(std::string &result)
168{
169    if (access(DUMP_FILE_PATH.c_str(), 0) < 0) {
170        if (mkdir(DUMP_FILE_PATH.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) {
171            DHLOGE("Create dir error");
172            return ERR_DH_AUDIO_FAILED;
173        }
174    }
175    DHLOGI("Start dump audio data.");
176    result.append("start dump...");
177    dumpAudioDataFlag_ = true;
178    return DH_SUCCESS;
179}
180
181int32_t DaudioHidumper::StopDumpData(std::string &result)
182{
183    DHLOGI("Stop dump audio data.");
184    result.append("stop dump...");
185    dumpAudioDataFlag_ = false;
186    return DH_SUCCESS;
187}
188
189bool DaudioHidumper::QueryDumpDataFlag()
190{
191    return dumpAudioDataFlag_;
192}
193
194void DaudioHidumper::ShowHelp(std::string &result)
195{
196    DHLOGI("Show help.");
197    result.append("Usage:dump  <command> [options]\n")
198        .append("Description:\n")
199        .append("-h            ")
200        .append(": show help\n")
201        .append("--sourceDevId ")
202        .append(": dump audio sourceDevId in the system\n")
203        .append("--sinkInfo    ")
204        .append(": dump sink info in the system\n")
205        .append("--ability     ")
206        .append(": dump current ability of the audio in the system\n")
207        .append("--startDump")
208        .append(": start dump audio data in the system /data/data/daudio\n")
209        .append("--stopDump")
210        .append(": stop dump audio data in the system\n");
211}
212
213int32_t DaudioHidumper::ShowIllegalInfomation(std::string &result)
214{
215    DHLOGI("Show illegal information.");
216    result.append("unknown command, -h for help.");
217    return DH_SUCCESS;
218}
219} // namespace DistributedHardware
220} // namespace OHOS