• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "system_ability_manager_dumper.h"
17 
18 #include "accesstoken_kit.h"
19 #include "ffrt_inner.h"
20 #include "file_ex.h"
21 #include "ipc_skeleton.h"
22 #include "system_ability_manager.h"
23 #include "if_local_ability_manager.h"
24 #include "ipc_payload_statistics.h"
25 #include "samgr_err_code.h"
26 
27 using namespace std;
28 namespace OHOS {
29 namespace {
30 constexpr const char* HIDUMPER_PROCESS_NAME = "hidumper_service";
31 constexpr const char* ARGS_QUERY_SA = "-sa";
32 constexpr const char* ARGS_QUERY_PROCESS = "-p";
33 constexpr const char* ARGS_QUERY_SA_IN_CURRENT_STATE = "-sm";
34 constexpr const char* ARGS_HELP = "-h";
35 constexpr const char* ARGS_QUERY_ALL = "-l";
36 constexpr const char* ARGS_FFRT_SEPARATOR = "|";
37 constexpr size_t MIN_ARGS_SIZE = 1;
38 constexpr size_t MAX_ARGS_SIZE = 2;
39 constexpr int32_t FFRT_DUMP_PROC_LEN = 2;
40 constexpr int32_t FFRT_DUMP_PIDS_INDEX = 1;
41 constexpr int FFRT_BUFFER_SIZE = 512 * 1024;
42 constexpr int LISTENER_BASE_INDEX = 1;
43 constexpr int32_t FFRT_METRIC_CMD_INDEX = 2;
44 constexpr int32_t FFRT_DUMP_METRIC_LEN = 3;
45 constexpr int32_t COLLECT_FFRT_METRIC_MAX_SIZE = 5000;
46 constexpr int32_t FFRT_STAT_SIZE = sizeof(ffrt_stat);
47 constexpr int32_t BUFFER_SIZE = FFRT_STAT_SIZE * COLLECT_FFRT_METRIC_MAX_SIZE;
48 constexpr int32_t DELAY_TIME = 60 * 1000;
49 constexpr const char* FFRT_STAT_STR_START = "--start-stat";
50 constexpr const char* FFRT_STAT_STR_STOP = "--stop-stat";
51 constexpr const char* FFRT_STAT_STR_GET = "--stat";
52 constexpr const char* IPC_STAT_STR_START = "--start-stat";
53 constexpr const char* IPC_STAT_STR_STOP = "--stop-stat";
54 constexpr const char* IPC_STAT_STR_GET = "--stat";
55 constexpr const char* IPC_STAT_STR_ALL = "all";
56 constexpr const char* IPC_STAT_STR_SAMGR = "samgr";
57 constexpr const char* IPC_DUMP_SUCCESS = " success\n";
58 constexpr const char* IPC_DUMP_FAIL = " fail\n";
59 
60 }
61 
62 std::shared_ptr<FFRTHandler> SystemAbilityManagerDumper::handler_ = nullptr;
63 char* SystemAbilityManagerDumper::ffrtMetricBuffer = nullptr;
64 bool SystemAbilityManagerDumper::collectEnable = false;
65 samgr::mutex SystemAbilityManagerDumper::ffrtMetricLock;
66 
ShowListenerHelp(string & result)67 void SystemAbilityManagerDumper::ShowListenerHelp(string& result)
68 {
69     result.append("SystemAbilityManager Listener Dump options:\n")
70         .append("  [-h] [cmd]...\n")
71         .append("cmd maybe one of:\n")
72         .append("  -sa [said]: query sa listener infos.\n")
73         .append("  -p [pid]: query process listener infos.\n")
74         .append("  -l [-sa | -p]: query all sa listener infos by [sa | process].\n");
75 }
76 
ListenerDumpProc(map<int32_t,list<SAListener>> & listeners,int32_t fd,const vector<string> & args)77 int32_t SystemAbilityManagerDumper::ListenerDumpProc(map<int32_t, list<SAListener>>& listeners,
78     int32_t fd, const vector<string>& args)
79 {
80     if (!CanDump()) {
81         HILOGE("Dump failed, not allowed");
82         return ERR_PERMISSION_DENIED;
83     }
84     string result;
85     GetListenerDumpProc(listeners, args, result);
86     return SaveDumpResultToFd(fd, result);
87 }
88 
GetListenerDumpProc(map<int32_t,list<SAListener>> & listeners,const vector<string> & args,string & result)89 void SystemAbilityManagerDumper::GetListenerDumpProc(map<int32_t, list<SAListener>>& listeners,
90     const vector<string>& args, string& result)
91 {
92     if (args.size() == MIN_ARGS_SIZE + 1) {
93         // -h
94         if (args[LISTENER_BASE_INDEX] == ARGS_HELP) {
95             ShowListenerHelp(result);
96             return;
97         }
98     } else if (args.size() == MAX_ARGS_SIZE + 1) {
99         // -l
100         if (args[LISTENER_BASE_INDEX] == ARGS_QUERY_ALL) {
101             // -sa
102             if (args[LISTENER_BASE_INDEX + 1] == ARGS_QUERY_SA) {
103                 ShowAllBySA(listeners, result);
104                 return;
105             }
106             // -p
107             if (args[LISTENER_BASE_INDEX + 1] == ARGS_QUERY_PROCESS) {
108                 ShowAllByCallingPid(listeners, result);
109                 return;
110             }
111         }
112         // -sa said
113         if (args[LISTENER_BASE_INDEX] == ARGS_QUERY_SA) {
114             int said = atoi(args[LISTENER_BASE_INDEX + 1].c_str());
115             ShowCallingPidBySA(listeners, said, result);
116             return;
117         }
118         // -p pid
119         if (args[LISTENER_BASE_INDEX] == ARGS_QUERY_PROCESS) {
120             int callingPid = atoi(args[LISTENER_BASE_INDEX + 1].c_str());
121             ShowSAByCallingPid(listeners, callingPid, result);
122             return;
123         }
124     }
125     IllegalInput(result);
126 }
127 
ShowAllBySA(map<int32_t,list<SAListener>> & listeners,string & result)128 void SystemAbilityManagerDumper::ShowAllBySA(map<int32_t, list<SAListener>>& listeners,
129     string& result)
130 {
131     result += "********************************ShowAllBySA********************************";
132     set<sptr<IRemoteObject>> listenerSet;
133     for (auto iter : listeners) {
134         if (iter.second.size() == 0) {
135             continue;
136         }
137         result += "\n\n--------------------------------SA:";
138         result += to_string(iter.first);
139         result += ", SubCnt:";
140         result += to_string(iter.second.size());
141         result += "--------------------------------";
142         map<int32_t, int32_t> pidCnt;
143         for (auto saListener : iter.second) {
144             pidCnt[saListener.callingPid]++;
145             listenerSet.insert(saListener.listener->AsObject());
146         }
147         for (auto iter : pidCnt) {
148             result += "\ncallingPid:";
149             result += to_string(iter.first);
150             result += ", cnt:";
151             result += to_string(iter.second);
152         }
153     }
154     result += "\n--------------------------------TotalListenerCnt:";
155     result += to_string(listenerSet.size());
156     result += "--------------------------------";
157     result += "\n***************************************************************************\n";
158 }
159 
ShowAllByCallingPid(map<int32_t,list<SAListener>> & listeners,string & result)160 void SystemAbilityManagerDumper::ShowAllByCallingPid(map<int32_t, list<SAListener>>& listeners,
161     string& result)
162 {
163     result += "********************************ShowAllByCallingPid********************************";
164     map<int32_t, list<pair<int32_t, sptr<ISystemAbilityStatusChange>>>> subscribeMap;
165     map<int32_t, set<sptr<IRemoteObject>>> pidListenerMap;
166     size_t totalSum = 0;
167     for (auto iter : listeners) {
168         int32_t said = iter.first;
169         for (auto saListener : iter.second) {
170             subscribeMap[saListener.callingPid].push_back({said, saListener.listener});
171             pidListenerMap[saListener.callingPid].insert(saListener.listener->AsObject());
172         }
173     }
174     vector<pair<int32_t, set<sptr<IRemoteObject>>>> vec(pidListenerMap.begin(), pidListenerMap.end());
175     auto cmp = [](const pair<int32_t, set<sptr<IRemoteObject>>>& p1,
176         const pair<int32_t, set<sptr<IRemoteObject>>>& p2) {
177         return p1.second.size() > p2.second.size();
178     };
179     sort(vec.begin(), vec.end(), cmp);
180     for (auto iter : vec) {
181         result += "\n\n--------------------------------CallingPid:";
182         result += to_string(iter.first);
183         result += ", ListenerCnt:";
184         result += to_string(iter.second.size());
185         result += "--------------------------------";
186         totalSum += iter.second.size();
187         map<int32_t, int32_t> saCnt;
188         for (auto p : subscribeMap[iter.first]) {
189             saCnt[p.first]++;
190         }
191         for (auto iter : saCnt) {
192             result += "\nSA:";
193             result += to_string(iter.first);
194             result += ", cnt:";
195             result += to_string(iter.second);
196         }
197     }
198     result += "\n--------------------------------TotalListenerCnt:";
199     result += to_string(totalSum);
200     result += "--------------------------------";
201     result += "\n***********************************************************************************\n";
202 }
203 
ShowCallingPidBySA(map<int32_t,list<SAListener>> & listeners,int32_t said,string & result)204 void SystemAbilityManagerDumper::ShowCallingPidBySA(map<int32_t, list<SAListener>>& listeners,
205     int32_t said, string& result)
206 {
207     result += "********************************ShowCallingPidBySA********************************";
208     result += "\n--------------------------------SA:";
209     result += to_string(said);
210     result += "--------------------------------";
211     map<int32_t, int32_t> pidCnt;
212     for (auto iter : listeners) {
213         if (iter.first == said) {
214             for (auto saListener : iter.second) {
215                 pidCnt[saListener.callingPid]++;
216             }
217             break;
218         }
219     }
220     int32_t totalSum = 0;
221     for (auto iter : pidCnt) {
222         result += "\ncallingPid:";
223         result += to_string(iter.first);
224         result += ", cnt:";
225         result += to_string(iter.second);
226         totalSum += iter.second;
227     }
228     result += "\n--------------------------------TotalSubCnt:";
229     result += to_string(totalSum);
230     result += "--------------------------------";
231     result += "\n**********************************************************************************\n";
232 }
233 
ShowSAByCallingPid(map<int32_t,list<SAListener>> & listeners,int32_t callingPid,string & result)234 void SystemAbilityManagerDumper::ShowSAByCallingPid(map<int32_t, list<SAListener>>& listeners,
235     int32_t callingPid, string& result)
236 {
237     result += "********************************ShowSAByCallingPid********************************";
238     result += "\n--------------------------------CallingPid:";
239     result += to_string(callingPid);
240     result += "--------------------------------";
241     map<int32_t, int32_t> saCnt;
242     set<sptr<IRemoteObject>> listenerSet;
243     for (auto iter : listeners) {
244         int32_t said = iter.first;
245         for (auto saListener : iter.second) {
246             if (saListener.callingPid == callingPid) {
247                 saCnt[said]++;
248                 listenerSet.insert(saListener.listener->AsObject());
249             }
250         }
251     }
252     for (auto iter : saCnt) {
253         result += "\nSA:";
254         result += to_string(iter.first);
255         result += ", cnt:";
256         result += to_string(iter.second);
257     }
258     result += "\n--------------------------------ListenerCnt:";
259     result += to_string(listenerSet.size());
260     result += "--------------------------------";
261     result += "\n**********************************************************************************\n";
262 }
263 
FfrtDumpProc(std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler,int32_t fd,const std::vector<std::string> & args)264 int32_t SystemAbilityManagerDumper::FfrtDumpProc(std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler,
265     int32_t fd, const std::vector<std::string>& args)
266 {
267     if (!CanDump()) {
268         HILOGE("Dump failed, not allowed");
269         return ERR_PERMISSION_DENIED;
270     }
271     std::string result;
272     if (args.size() < FFRT_DUMP_PROC_LEN || args[FFRT_DUMP_PIDS_INDEX].empty()) {
273         HILOGE("FfrtDump param pid not exist");
274         IllegalInput(result);
275         return SaveDumpResultToFd(fd, result);
276     }
277     if (args.size() == FFRT_DUMP_PROC_LEN) {
278         GetFfrtDumpInfoProc(abilityStateScheduler, args, result);
279         return SaveDumpResultToFd(fd, result);
280     }
281     if (args.size() == FFRT_DUMP_METRIC_LEN) {
282         GetFfrtLoadMetrics(abilityStateScheduler, fd, args, result);
283         return SaveDumpResultToFd(fd, result);
284     }
285     IllegalInput(result);
286     return SaveDumpResultToFd(fd, result);
287 }
288 
GetFfrtLoadMetrics(std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler,int32_t fd,const std::vector<std::string> & args,std::string & result)289 void SystemAbilityManagerDumper::GetFfrtLoadMetrics(std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler,
290     int32_t fd, const std::vector<std::string>& args, std::string& result)
291 {
292     std::string pidStr = args[FFRT_DUMP_PIDS_INDEX];
293     std::vector<int32_t> processIds;
294     FfrtDumpParser(processIds, pidStr);
295     if (processIds.empty()) {
296         HILOGE("FfrtDumpParser parse failed, illegal input processIdsStr %{public}s ", pidStr.c_str());
297         IllegalInput(result);
298         return;
299     }
300     int32_t cmd = -1;
301     if (!FfrtStatCmdParser(cmd, args)) {
302         IllegalInput(result);
303         return;
304     }
305     CollectFfrtMetricInfoInProcs(fd, processIds, abilityStateScheduler, cmd, result);
306 }
307 
FfrtStatCmdParser(int32_t & cmd,const std::vector<std::string> & args)308 bool SystemAbilityManagerDumper::FfrtStatCmdParser(int32_t& cmd, const std::vector<std::string>& args)
309 {
310     if (args[FFRT_METRIC_CMD_INDEX] == FFRT_STAT_STR_START) {
311         cmd = FFRT_STAT_CMD_START;
312     } else if (args[FFRT_METRIC_CMD_INDEX] == FFRT_STAT_STR_STOP) {
313         cmd = FFRT_STAT_CMD_STOP;
314     } else if (args[FFRT_METRIC_CMD_INDEX] == FFRT_STAT_STR_GET) {
315         cmd = FFRT_STAT_CMD_GET;
316     } else {
317         return false;
318     }
319     return true;
320 }
321 
CollectFfrtMetricInfoInProcs(int32_t fd,const std::vector<int32_t> & processIds,std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler,int32_t cmd,std::string & result)322 void SystemAbilityManagerDumper::CollectFfrtMetricInfoInProcs(int32_t fd, const std::vector<int32_t>& processIds,
323     std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler, int32_t cmd, std::string& result)
324 {
325     for (const int32_t pid : processIds) {
326         if (pid == getpid()) {
327             CollectFfrtStatistics(cmd, result);
328             continue;
329         }
330         sptr<ILocalAbilityManager> obj = GetProcByProcessId(abilityStateScheduler, pid);
331         if (obj == nullptr) {
332             HILOGE("CollectFfrtMetricInfoInProcs GetSystemProcess failed");
333             result.append("process " + std::to_string(pid) + " not found!\n");
334             continue;
335         }
336         obj->FfrtStatCmdProc(fd, cmd);
337     }
338 }
339 
StartFfrtStatistics(std::string & result)340 bool SystemAbilityManagerDumper::StartFfrtStatistics(std::string& result)
341 {
342     if (collectEnable) {
343         result.append("collect has been started\n");
344         return false;
345     }
346     ClearFfrtStatisticsBufferLocked();
347     ffrtMetricBuffer = new char[BUFFER_SIZE]();
348     auto ret = ffrt_dump(ffrt_dump_cmd_t::DUMP_START_STAT, ffrtMetricBuffer, BUFFER_SIZE);
349     if (ret != ERR_OK) {
350         ClearFfrtStatisticsBufferLocked();
351         result.append("collect start failed\n");
352         return false;
353     }
354     collectEnable = true;
355     result.append("collect start success\n");
356     if (handler_ == nullptr) {
357         handler_ = std::make_shared<FFRTHandler>("ffrtDumpHandler");
358     }
359     HILOGI("StartFfrtStatistics PostTask delayTime:%{public}dms", DELAY_TIME);
360     handler_->PostTask(ClearFfrtStatistics, "ClearFfrtStatistics", DELAY_TIME);
361     return true;
362 }
363 
StopFfrtStatistics(std::string & result)364 bool SystemAbilityManagerDumper::StopFfrtStatistics(std::string& result)
365 {
366     if (!collectEnable) {
367         result.append("collect has not been started\n");
368         return false;
369     }
370     collectEnable = false;
371     auto ret = ffrt_dump(ffrt_dump_cmd_t::DUMP_STOP_STAT, ffrtMetricBuffer, BUFFER_SIZE);
372     if (ret != ERR_OK) {
373         ClearFfrtStatisticsBufferLocked();
374         result.append("collect stop failed\n");
375         return false;
376     }
377     result.append("collect stop success\n");
378     return true;
379 }
380 
GetFfrtStatistics(std::string & result)381 bool SystemAbilityManagerDumper::GetFfrtStatistics(std::string& result)
382 {
383     if (collectEnable) {
384         result.append("collect has not been stopped\n");
385         return false;
386     }
387     if (ffrtMetricBuffer == nullptr) {
388         result.append("info not collected\n");
389         return false;
390     }
391     FfrtStatisticsParser(result);
392     ClearFfrtStatisticsBufferLocked();
393     handler_ = nullptr;
394     return true;
395 }
396 
FfrtStatisticsParser(std::string & result)397 void SystemAbilityManagerDumper::FfrtStatisticsParser(std::string& result)
398 {
399     ffrt_stat* currentStat = (ffrt_stat*)ffrtMetricBuffer;
400     char* lastStat = ffrtMetricBuffer + BUFFER_SIZE;
401     std::string taskInfo;
402     uint64_t maxTime = 0;
403     uint64_t minTime = std::numeric_limits<uint64_t>::max();
404     uint64_t sumTime = 0;
405     uint64_t avgTime = 0;
406     uint64_t count = 0;
407     while ((char*)currentStat < lastStat && std::strcmp(currentStat->taskName, "") != 0) {
408         if (currentStat->startTime > currentStat->endTime) {
409             currentStat = (ffrt_stat*)((char*)currentStat + FFRT_STAT_SIZE);
410             continue;
411         }
412         auto duration = currentStat->endTime - currentStat->startTime;
413         sumTime += duration;
414         maxTime = std::max(maxTime, duration);
415         minTime = std::min(minTime, duration);
416         ++count;
417         taskInfo.append(currentStat->taskName);
418         taskInfo.append(" " + ToString(currentStat->startTime));
419         taskInfo.append(" " + ToString(currentStat->endTime) + "\n");
420         currentStat = (ffrt_stat*)((char*)currentStat + FFRT_STAT_SIZE);
421     }
422     if (count == 0) {
423         minTime = 0;
424     } else {
425         avgTime = sumTime / count;
426     }
427     result.append("sumTime:" + ToString(sumTime) + " maxTime:" + ToString(maxTime));
428     result.append(" minTime:" + ToString(minTime) + " avgTime:" + ToString(avgTime));
429     result.append(" cntTime:" + ToString(count) + "\n");
430     result.append("-------------------------------------------------------------------------------------------\n");
431     result.append("taskName                                                        startTime(us)   endTime(us)\n");
432     result.append("-------------------------------------------------------------------------------------------\n");
433     result.append(taskInfo);
434     result.append("-------------------------------------------------------------------------------------------\n");
435 }
436 
ClearFfrtStatisticsBufferLocked()437 void SystemAbilityManagerDumper::ClearFfrtStatisticsBufferLocked()
438 {
439     if (ffrtMetricBuffer != nullptr) {
440         delete[] ffrtMetricBuffer;
441         ffrtMetricBuffer = nullptr;
442         HILOGI("ClearFfrtStatisticsBuffer success");
443     }
444     if (handler_ != nullptr) {
445         handler_->RemoveTask("ClearFfrtStatistics");
446     }
447 }
448 
ClearFfrtStatistics()449 void SystemAbilityManagerDumper::ClearFfrtStatistics()
450 {
451     HILOGW("ClearFfrtStatistics start");
452     std::lock_guard<samgr::mutex> autoLock(ffrtMetricLock);
453     if (collectEnable) {
454         auto ret = ffrt_dump(ffrt_dump_cmd_t::DUMP_STOP_STAT, ffrtMetricBuffer, BUFFER_SIZE);
455         if (ret != ERR_OK) {
456             HILOGE("ClearFfrtStatistics stop ffrt_dump err:%{public}d", ret);
457         }
458         collectEnable = false;
459     }
460     ClearFfrtStatisticsBufferLocked();
461 }
462 
CollectFfrtStatistics(int32_t cmd,std::string & result)463 bool SystemAbilityManagerDumper::CollectFfrtStatistics(int32_t cmd, std::string& result)
464 {
465     std::lock_guard<samgr::mutex> autoLock(ffrtMetricLock);
466     result.append("pid:" + ToString(getpid()) + " ");
467     auto ret = false;
468     switch (cmd) {
469         case FFRT_STAT_CMD_START: {
470             ret = StartFfrtStatistics(result);
471             break;
472         }
473         case FFRT_STAT_CMD_STOP: {
474             ret = StopFfrtStatistics(result);
475             break;
476         }
477         case FFRT_STAT_CMD_GET: {
478             ret = GetFfrtStatistics(result);
479             break;
480         }
481         default:
482             break;
483     }
484     return ret;
485 }
486 
GetProcByProcessId(std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler,int32_t processId)487 sptr<ILocalAbilityManager> SystemAbilityManagerDumper::GetProcByProcessId(
488     std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler, int32_t processId)
489 {
490     std::u16string processName;
491     int32_t queryResult = abilityStateScheduler->GetProcessNameByProcessId(processId, processName);
492     if (queryResult != ERR_OK) {
493         HILOGE("GetProcessNameByProcessId failed, pid %{public}d not exist", processId);
494         return nullptr;
495     }
496     sptr<ILocalAbilityManager> obj =
497         iface_cast<ILocalAbilityManager>(SystemAbilityManager::GetInstance()->GetSystemProcess(processName));
498     if (obj == nullptr) {
499         HILOGE("GetSystemProcess failed, pid:%{public}d processName:%{public}s not exist",
500             processId, Str16ToStr8(processName).c_str());
501     }
502     return obj;
503 }
504 
GetFfrtDumpInfoProc(std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler,const std::vector<std::string> & args,std::string & result)505 bool SystemAbilityManagerDumper::GetFfrtDumpInfoProc(std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler,
506     const std::vector<std::string>& args, std::string& result)
507 {
508     std::string pidStr = args[FFRT_DUMP_PIDS_INDEX];
509     std::vector<int32_t> processIds;
510     FfrtDumpParser(processIds, pidStr);
511     if (processIds.empty()) {
512         HILOGE("FfrtDumpParser parse failed, illegal input processIdsStr %{public}s ", pidStr.c_str());
513         IllegalInput(result);
514         return false;
515     }
516     HILOGD("FfrtDumpProc: processIdsSize=%{public}zu", processIds.size());
517     for (const int32_t pid : processIds) {
518         if (pid == getpid()) {
519             GetSAMgrFfrtInfo(result);
520             continue;
521         }
522         DumpFfrtInfoInProc(abilityStateScheduler, pid, result);
523     }
524     return true;
525 }
526 
FfrtDumpParser(std::vector<int32_t> & processIds,const std::string & processIdsStr)527 bool SystemAbilityManagerDumper::FfrtDumpParser(std::vector<int32_t>& processIds, const std::string& processIdsStr)
528 {
529     std::string processIdsVecStr = processIdsStr + ARGS_FFRT_SEPARATOR;
530     std::size_t pos = processIdsVecStr.find(ARGS_FFRT_SEPARATOR);
531     while (pos != std::string::npos) {
532         std::string processIdStr = processIdsVecStr.substr(0, pos);
533         processIdsVecStr = processIdsVecStr.substr(pos + 1, processIdsVecStr.size() - pos - 1);
534         pos = processIdsVecStr.find(ARGS_FFRT_SEPARATOR);
535         int32_t processId = -1;
536         if (!StrToInt(processIdStr, processId)) {
537             HILOGE("StrToInt processIdStr %{public}s error", processIdStr.c_str());
538             continue;
539         }
540         if (processId > 0) {
541             processIds.emplace_back(processId);
542         }
543     }
544     return true;
545 }
546 
GetSAMgrFfrtInfo(std::string & result)547 void SystemAbilityManagerDumper::GetSAMgrFfrtInfo(std::string& result)
548 {
549     char* buffer = new char[FFRT_BUFFER_SIZE + 1]();
550     buffer[FFRT_BUFFER_SIZE] = 0;
551     ffrt_dump(ffrt_dump_cmd_t::DUMP_INFO_ALL, buffer, FFRT_BUFFER_SIZE);
552     if (strlen(buffer) == 0) {
553         HILOGE("get samgr FfrtDumperInfo failed");
554         delete[] buffer;
555         return;
556     }
557     std::string ffrtDumpInfoStr(buffer);
558     result.append(ffrtDumpInfoStr + "\n");
559     delete[] buffer;
560 }
561 
DumpFfrtInfoInProc(std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler,int32_t pid,std::string & result)562 void SystemAbilityManagerDumper::DumpFfrtInfoInProc(
563     std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler, int32_t pid, std::string& result)
564 {
565     sptr<ILocalAbilityManager> obj = GetProcByProcessId(abilityStateScheduler, pid);
566     if (obj == nullptr) {
567         HILOGE("DumpFfrtInfoInProc GetSystemProcess failed");
568         result.append("process " + std::to_string(pid) + " not found!\n");
569         return;
570     }
571     std::string resultForProcess;
572     if (!obj->FfrtDumperProc(resultForProcess)) {
573         HILOGE("safwk FfrtDumperProc execute failed");
574         return;
575     }
576     result.append(resultForProcess + "\n");
577 }
578 
SaveDumpResultToFd(int32_t fd,const std::string & result)579 int32_t SystemAbilityManagerDumper::SaveDumpResultToFd(int32_t fd, const std::string& result)
580 {
581     if (!SaveStringToFd(fd, result)) {
582         HILOGE("save to fd failed");
583         return SAVE_FD_FAIL;
584     }
585     HILOGD("save to fd success");
586     return ERR_OK;
587 }
588 
StartSamgrIpcStatistics(std::string & result)589 bool SystemAbilityManagerDumper::StartSamgrIpcStatistics(std::string& result)
590 {
591     result = std::string("StartIpcStatistics pid:") + std::to_string(getpid());
592     bool ret = IPCPayloadStatistics::StartStatistics();
593     result += ret ? IPC_DUMP_SUCCESS : IPC_DUMP_FAIL;
594     return ret;
595 }
596 
StopSamgrIpcStatistics(std::string & result)597 bool SystemAbilityManagerDumper::StopSamgrIpcStatistics(std::string& result)
598 {
599     result = std::string("StopSamgrIpcStatistics pid:") + std::to_string(getpid());
600     bool ret = IPCPayloadStatistics::StopStatistics();
601     result += ret ? IPC_DUMP_SUCCESS : IPC_DUMP_FAIL;
602     return ret;
603 }
604 
GetSamgrIpcStatistics(std::string & result)605 bool SystemAbilityManagerDumper::GetSamgrIpcStatistics(std::string& result)
606 {
607     result += "********************************GlobalStatisticsInfo********************************";
608     result += "\nCurrentPid:";
609     result += std::to_string(getpid());
610     result += "\nTotalCount:";
611     result += std::to_string(IPCPayloadStatistics::GetTotalCount());
612     result += "\nTotalTimeCost:";
613     result += std::to_string(IPCPayloadStatistics::GetTotalCost());
614     std::vector<int32_t> pids;
615     pids = IPCPayloadStatistics::GetPids();
616     for (unsigned int i = 0; i < pids.size(); i++) {
617         result += "\n--------------------------------ProcessStatisticsInfo-------------------------------";
618         result += "\nCallingPid:";
619         result += std::to_string(pids[i]);
620         result += "\nCallingPidTotalCount:";
621         result += std::to_string(IPCPayloadStatistics::GetCount(pids[i]));
622         result += "\nCallingPidTotalTimeCost:";
623         result += std::to_string(IPCPayloadStatistics::GetCost(pids[i]));
624         std::vector<IPCInterfaceInfo> intfs;
625         intfs = IPCPayloadStatistics::GetDescriptorCodes(pids[i]);
626         for (unsigned int j = 0; j < intfs.size(); j++) {
627             result += "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~InterfaceStatisticsInfo~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
628             result += "\nDescriptorCode:";
629             result += Str16ToStr8(intfs[j].desc) + std::string("_") + std::to_string(intfs[j].code);
630             result += "\nDescriptorCodeCount:";
631             result += std::to_string(
632                 IPCPayloadStatistics::GetDescriptorCodeCount(pids[i], intfs[j].desc, intfs[j].code));
633             result += "\nDescriptorCodeTimeCost:";
634             result += "\nTotal:";
635             result += std::to_string(
636                 IPCPayloadStatistics::GetDescriptorCodeCost(pids[i], intfs[j].desc, intfs[j].code).totalCost);
637             result += " | Max:";
638             result += std::to_string(
639                 IPCPayloadStatistics::GetDescriptorCodeCost(pids[i], intfs[j].desc, intfs[j].code).maxCost);
640             result += " | Min:";
641             result += std::to_string(
642                 IPCPayloadStatistics::GetDescriptorCodeCost(pids[i], intfs[j].desc, intfs[j].code).minCost);
643             result += " | Avg:";
644             result += std::to_string(
645                 IPCPayloadStatistics::GetDescriptorCodeCost(pids[i], intfs[j].desc, intfs[j].code).averCost);
646             result += "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
647         }
648         result += "\n------------------------------------------------------------------------------------";
649     }
650     result += "\n************************************************************************************\n";
651     return true;
652 }
653 
IpcDumpIsAllProcess(const std::string & processName)654 bool SystemAbilityManagerDumper::IpcDumpIsAllProcess(const std::string& processName)
655 {
656     return processName == IPC_STAT_STR_ALL;
657 }
658 
IpcDumpIsSamgr(const std::string & processName)659 bool SystemAbilityManagerDumper::IpcDumpIsSamgr(const std::string& processName)
660 {
661     return processName == IPC_STAT_STR_SAMGR;
662 }
663 
IpcDumpCmdParser(int32_t & cmd,const std::vector<std::string> & args)664 bool SystemAbilityManagerDumper::IpcDumpCmdParser(int32_t& cmd, const std::vector<std::string>& args)
665 {
666     if (!CanDump()) {
667         HILOGE("IPC Dump failed, not allowed");
668         return false;
669     }
670 
671     if (args.size() < IPC_STAT_CMD_LEN) {
672         HILOGE("IPC Dump failed, length error");
673         return false;
674     }
675 
676     if (args[IPC_STAT_CMD_INDEX] == IPC_STAT_STR_START) {
677         cmd = IPC_STAT_CMD_START;
678     } else if (args[IPC_STAT_CMD_INDEX] == IPC_STAT_STR_STOP) {
679         cmd = IPC_STAT_CMD_STOP;
680     } else if (args[IPC_STAT_CMD_INDEX] == IPC_STAT_STR_GET) {
681         cmd = IPC_STAT_CMD_GET;
682     } else {
683         return false;
684     }
685     return true;
686 }
687 
Dump(std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler,const std::vector<std::string> & args,std::string & result)688 bool SystemAbilityManagerDumper::Dump(std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler,
689     const std::vector<std::string>& args, std::string& result)
690 {
691     if (!CanDump()) {
692         HILOGE("Dump failed, not allowed");
693         return false;
694     }
695     if (args.size() == MIN_ARGS_SIZE) {
696         // -l
697         if (args[0] == ARGS_QUERY_ALL) {
698             ShowAllSystemAbilityInfo(abilityStateScheduler, result);
699             return true;
700         }
701         // -h
702         if (args[0] == ARGS_HELP) {
703             ShowHelp(result);
704             return true;
705         }
706     }
707     if (args.size() == MAX_ARGS_SIZE) {
708         // -sa said
709         if (args[0] == ARGS_QUERY_SA) {
710             int said = atoi(args[1].c_str());
711             ShowSystemAbilityInfo(said, abilityStateScheduler, result);
712             return true;
713         }
714         // -p processname
715         if (args[0] == ARGS_QUERY_PROCESS) {
716             ShowProcessInfo(args[1], abilityStateScheduler, result);
717             return true;
718         }
719         // -sm state
720         if (args[0] == ARGS_QUERY_SA_IN_CURRENT_STATE) {
721             ShowAllSystemAbilityInfoInState(args[1], abilityStateScheduler, result);
722             return true;
723         }
724     }
725     IllegalInput(result);
726     return false;
727 }
728 
CanDump()729 bool SystemAbilityManagerDumper::CanDump()
730 {
731     uint32_t accessToken = IPCSkeleton::GetCallingTokenID();
732     Security::AccessToken::NativeTokenInfo nativeTokenInfo;
733     int32_t result = Security::AccessToken::AccessTokenKit::GetNativeTokenInfo(accessToken, nativeTokenInfo);
734     if (result == ERR_OK && nativeTokenInfo.processName == HIDUMPER_PROCESS_NAME) {
735         return true;
736     }
737     return false;
738 }
739 
ShowHelp(std::string & result)740 void SystemAbilityManagerDumper::ShowHelp(std::string& result)
741 {
742     result.append("SystemAbilityManager Dump options:\n")
743         .append("  [-h] [cmd]...\n")
744         .append("cmd maybe one of:\n")
745         .append("  -sa said: query sa state infos.\n")
746         .append("  -p processname: query process state infos.\n")
747         .append("  -sm state: query all sa based on state infos.\n")
748         .append("  -l: query all sa state infos.\n")
749         .append("  --listener -h: help text for listener.\n")
750         .append("  --ffrt [pid1|pid2] --start-stat/--stop-stat/--stat: start/stop/get")
751         .append(" the FFRT load statistics of a process.\n")
752         .append("  --ffrt [pid1|pid2]: query the FFRT dump infos of a process.\n")
753         .append("  --ipc procname/all --start-stat/--stop-stat/--stat: start/stop/get")
754         .append(" the IPC load statistics of a process.\n");
755 }
756 
ShowAllSystemAbilityInfo(std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler,std::string & result)757 void SystemAbilityManagerDumper::ShowAllSystemAbilityInfo(
758     std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler, std::string& result)
759 {
760     if (abilityStateScheduler == nullptr) {
761         HILOGE("abilityStateScheduler is nullptr");
762         return;
763     }
764     abilityStateScheduler->GetAllSystemAbilityInfo(result);
765 }
766 
ShowSystemAbilityInfo(int32_t said,std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler,std::string & result)767 void SystemAbilityManagerDumper::ShowSystemAbilityInfo(int32_t said,
768     std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler, std::string& result)
769 {
770     if (abilityStateScheduler == nullptr) {
771         HILOGE("abilityStateScheduler is nullptr");
772         return;
773     }
774     abilityStateScheduler->GetSystemAbilityInfo(said, result);
775 }
776 
ShowProcessInfo(const std::string & processName,std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler,std::string & result)777 void SystemAbilityManagerDumper::ShowProcessInfo(const std::string& processName,
778     std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler, std::string& result)
779 {
780     if (abilityStateScheduler == nullptr) {
781         HILOGE("abilityStateScheduler is nullptr");
782         return;
783     }
784     abilityStateScheduler->GetProcessInfo(processName, result);
785 }
786 
ShowAllSystemAbilityInfoInState(const std::string & state,std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler,std::string & result)787 void SystemAbilityManagerDumper::ShowAllSystemAbilityInfoInState(const std::string& state,
788     std::shared_ptr<SystemAbilityStateScheduler> abilityStateScheduler, std::string& result)
789 {
790     if (abilityStateScheduler == nullptr) {
791         HILOGE("abilityStateScheduler is nullptr");
792         return;
793     }
794     abilityStateScheduler->GetAllSystemAbilityInfoByState(state, result);
795 }
796 
IllegalInput(std::string & result)797 void SystemAbilityManagerDumper::IllegalInput(std::string& result)
798 {
799     result.append("The arguments are illegal and you can enter '-h' for help.\n");
800 }
801 } // namespace OHOS