1 /*
2  * Copyright (C) 2021 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 #include "executor/sa_dumper.h"
16 #include <cstdio>
17 #include <ipc_skeleton.h>
18 #include <sstream>
19 #include <thread>
20 #include <unistd.h>
21 #include "dump_utils.h"
22 #include "file_ex.h"
23 #include "securec.h"
24 
25 namespace OHOS {
26 namespace HiviewDFX {
27 namespace {
28 static const std::string SEPARATOR_TEMPLATE = "----------------------------------";
29 static const std::string ABILITY_LINE = "-------------------------------[ability]-------------------------------";
30 const std::string LOG_TXT = "log.txt";
31 using StringMatrix = std::shared_ptr<std::vector<std::vector<std::string>>>;
32 
33 } // namespace
34 
SADumper(void)35 SADumper::SADumper(void)
36 {
37 }
38 
~SADumper(void)39 SADumper::~SADumper(void)
40 {
41 }
42 
PreExecute(const std::shared_ptr<DumperParameter> & parameter,StringMatrix dump_datas)43 DumpStatus SADumper::PreExecute(const std::shared_ptr<DumperParameter> &parameter, StringMatrix dump_datas)
44 {
45     result_ = dump_datas;
46     names_ = ptrDumpCfg_->args_->GetNameList();
47     bool isZip = parameter->GetOpts().IsDumpZip();
48     auto callback = parameter->getClientCallback();
49     if (callback == nullptr) {
50         DUMPER_HILOGE(MODULE_COMMON, "PreExecute error|callback is nullptr");
51         return DumpStatus::DUMP_FAIL;
52     }
53     std::string logDefaultPath_ = callback->GetFolder() + LOG_TXT;
54     if (isZip) {
55         outputFd_ = DumpUtils::FdToWrite(logDefaultPath_);
56     } else {
57         outputFd_ = parameter->getClientCallback()->GetOutputFd();
58     }
59 
60     StringVector args = ptrDumpCfg_->args_->GetArgList();
61     if (!args.empty() && names_.size() == 1) {
62         std::transform(args.begin(), args.end(), std::back_inserter(args_), Str8ToStr16);
63         std::stringstream argsStr;
64         for (std::string arg : args) {
65             argsStr << arg << " ";
66         }
67         argsStr_ = argsStr.str();
68     }
69     return DumpStatus::DUMP_OK;
70 }
71 
GetData(const std::string & name,const sptr<ISystemAbilityManager> & sam)72 DumpStatus SADumper::GetData(const std::string &name, const sptr<ISystemAbilityManager> &sam)
73 {
74     int id = DumpUtils::StrToId(name);
75     if (id == -1) {
76         DUMPER_HILOGE(MODULE_SERVICE, "no such ability id '%{public}s'\n", name.c_str());
77         return DumpStatus::DUMP_FAIL;
78     }
79     sptr<IRemoteObject> sa = sam->CheckSystemAbility(id);
80     if (sa == nullptr) {
81         DUMPER_HILOGE(MODULE_SERVICE, "no such system ability %{public}s\n", name.c_str());
82         return DumpStatus::DUMP_FAIL;
83     }
84     std::stringstream ss;
85     ss << SEPARATOR_TEMPLATE << DumpUtils::ConvertSaIdToSaName(name) << SEPARATOR_TEMPLATE;
86     std::lock_guard<std::mutex> lock(mutex_);
87     SaveStringToFd(outputFd_, "\n" + ABILITY_LINE + "\n");
88     SaveStringToFd(outputFd_, "\n\n" + ss.str() + "\n");
89     int result = sa->Dump(outputFd_, args_);
90     if (result != ERR_OK) {
91         DUMPER_HILOGE(MODULE_SERVICE, "system ability:%{public}s dump fail!ret:%{public}d\n", name.c_str(), result);
92     }
93     int32_t calllingPid = IPCSkeleton::GetCallingPid();
94     DUMPER_HILOGI(MODULE_COMMON, "SA name:%{public}s dump success, cmd:%{public}s, calllingPid=%{public}d!",
95         name.c_str(), argsStr_.c_str(), calllingPid);
96     return DumpStatus::DUMP_OK;
97 }
98 
Execute()99 DumpStatus SADumper::Execute()
100 {
101     sptr<ISystemAbilityManager> sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
102     if (sam == nullptr) {
103         DUMPER_HILOGE(MODULE_SERVICE, "get samgr fail!");
104         return DumpStatus::DUMP_FAIL;
105     }
106     if (names_.empty()) {
107         U16StringVector vct = sam->ListSystemAbilities();
108         std::transform(vct.begin(), vct.end(), std::back_inserter(names_), Str16ToStr8);
109     }
110     for (size_t i = 0; i < names_.size(); ++i) {
111         if (GetData(names_[i], sam) != DumpStatus::DUMP_OK) {
112             DUMPER_HILOGI(MODULE_SERVICE, "system ability:%{public}s execute fail!\n", names_[i].c_str());
113         }
114     }
115     return DumpStatus::DUMP_OK;
116 }
117 
AfterExecute()118 DumpStatus SADumper::AfterExecute()
119 {
120     return DumpStatus::DUMP_OK;
121 }
122 } // namespace HiviewDFX
123 } // namespace OHOS
124