1020a203aSopenharmony_ci/* 2020a203aSopenharmony_ci * Copyright (C) 2023 Huawei Device Co., Ltd. 3020a203aSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4020a203aSopenharmony_ci * you may not use this file except in compliance with the License. 5020a203aSopenharmony_ci * You may obtain a copy of the License at 6020a203aSopenharmony_ci * 7020a203aSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8020a203aSopenharmony_ci * 9020a203aSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10020a203aSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11020a203aSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12020a203aSopenharmony_ci * See the License for the specific language governing permissions and 13020a203aSopenharmony_ci * limitations under the License. 14020a203aSopenharmony_ci */ 15020a203aSopenharmony_ci#include "shell_catcher.h" 16020a203aSopenharmony_ci#include <regex> 17020a203aSopenharmony_ci#include <unistd.h> 18020a203aSopenharmony_ci#include <sys/wait.h> 19020a203aSopenharmony_ci#include "hiview_logger.h" 20020a203aSopenharmony_ci#include "common_utils.h" 21020a203aSopenharmony_ci#include "log_catcher_utils.h" 22020a203aSopenharmony_ci#include "securec.h" 23020a203aSopenharmony_ci#include "time_util.h" 24020a203aSopenharmony_cinamespace OHOS { 25020a203aSopenharmony_cinamespace HiviewDFX { 26020a203aSopenharmony_ciDEFINE_LOG_LABEL(0xD002D01, "EventLogger-ShellCatcher"); 27020a203aSopenharmony_ciShellCatcher::ShellCatcher() : EventLogCatcher() 28020a203aSopenharmony_ci{ 29020a203aSopenharmony_ci name_ = "ShellCatcher"; 30020a203aSopenharmony_ci} 31020a203aSopenharmony_ci 32020a203aSopenharmony_cibool ShellCatcher::Initialize(const std::string& cmd, int type, int catcherPid) 33020a203aSopenharmony_ci{ 34020a203aSopenharmony_ci catcherCmd_ = cmd; 35020a203aSopenharmony_ci catcherType_ = CATCHER_TYPE(type); 36020a203aSopenharmony_ci pid_ = catcherPid; 37020a203aSopenharmony_ci description_ = "catcher cmd: " + catcherCmd_ + " "; 38020a203aSopenharmony_ci return true; 39020a203aSopenharmony_ci} 40020a203aSopenharmony_ci 41020a203aSopenharmony_civoid ShellCatcher::SetEvent(std::shared_ptr<SysEvent> event) 42020a203aSopenharmony_ci{ 43020a203aSopenharmony_ci event_ = event; 44020a203aSopenharmony_ci} 45020a203aSopenharmony_ci 46020a203aSopenharmony_ciint ShellCatcher::DoChildProcesscatcher(int writeFd) 47020a203aSopenharmony_ci{ 48020a203aSopenharmony_ci int ret = -1; 49020a203aSopenharmony_ci switch (catcherType_) { 50020a203aSopenharmony_ci case CATCHER_INPUT_EVENT_HILOG: 51020a203aSopenharmony_ci ret = execl("/system/bin/hilog", "hilog", "-T", "InputKeyFlow", "-e", 52020a203aSopenharmony_ci std::to_string(pid_).c_str(), "-x", nullptr); 53020a203aSopenharmony_ci break; 54020a203aSopenharmony_ci case CATCHER_INPUT_HILOG: 55020a203aSopenharmony_ci ret = execl("/system/bin/hilog", "hilog", "-T", "InputKeyFlow", "-x", nullptr); 56020a203aSopenharmony_ci break; 57020a203aSopenharmony_ci case CATCHER_EEC: 58020a203aSopenharmony_ci { 59020a203aSopenharmony_ci std::string cmd = "-b EventExclusiveCommander getAllEventExclusiveCaller"; 60020a203aSopenharmony_ci ret = execl("/system/bin/hidumper", "hidumper", "-s", "4606", "-a", cmd.c_str(), nullptr); 61020a203aSopenharmony_ci } 62020a203aSopenharmony_ci break; 63020a203aSopenharmony_ci case CATCHER_GEC: 64020a203aSopenharmony_ci { 65020a203aSopenharmony_ci std::string cmd = "-b SCBGestureManager getAllGestureEnableCaller"; 66020a203aSopenharmony_ci ret = execl("/system/bin/hidumper", "hidumper", "-s", "4606", "-a", cmd.c_str(), nullptr); 67020a203aSopenharmony_ci } 68020a203aSopenharmony_ci break; 69020a203aSopenharmony_ci case CATCHER_UI: 70020a203aSopenharmony_ci { 71020a203aSopenharmony_ci std::string cmd = "-p 0"; 72020a203aSopenharmony_ci ret = execl("/system/bin/hidumper", "hidumper", "-s", "4606", "-a", cmd.c_str(), nullptr); 73020a203aSopenharmony_ci } 74020a203aSopenharmony_ci break; 75020a203aSopenharmony_ci default: 76020a203aSopenharmony_ci break; 77020a203aSopenharmony_ci } 78020a203aSopenharmony_ci return ret; 79020a203aSopenharmony_ci} 80020a203aSopenharmony_ci 81020a203aSopenharmony_ciint ShellCatcher::CaDoInChildProcesscatcher(int writeFd) 82020a203aSopenharmony_ci{ 83020a203aSopenharmony_ci int ret = -1; 84020a203aSopenharmony_ci switch (catcherType_) { 85020a203aSopenharmony_ci case CATCHER_HILOG: 86020a203aSopenharmony_ci ret = execl("/system/bin/hilog", "hilog", "-x", nullptr); 87020a203aSopenharmony_ci break; 88020a203aSopenharmony_ci case CATCHER_LIGHT_HILOG: 89020a203aSopenharmony_ci ret = execl("/system/bin/hilog", "hilog", "-z", "1000", "-P", std::to_string(pid_).c_str(), 90020a203aSopenharmony_ci nullptr); 91020a203aSopenharmony_ci break; 92020a203aSopenharmony_ci case CATCHER_DAM: 93020a203aSopenharmony_ci ret = execl("/system/bin/hidumper", "hidumper", "-s", "1910", "-a", "DumpAppMap", nullptr); 94020a203aSopenharmony_ci break; 95020a203aSopenharmony_ci case CATCHER_SCBWMS: 96020a203aSopenharmony_ci case CATCHER_SCBWMSEVT: 97020a203aSopenharmony_ci { 98020a203aSopenharmony_ci std::string cmdSuffix = (catcherType_ == CATCHER_SCBWMS) ? " -simplify" : " -event"; 99020a203aSopenharmony_ci std::string cmd = "-w " + focusWindowId_ + cmdSuffix; 100020a203aSopenharmony_ci ret = execl("/system/bin/hidumper", "hidumper", "-s", "WindowManagerService", "-a", 101020a203aSopenharmony_ci cmd.c_str(), nullptr); 102020a203aSopenharmony_ci } 103020a203aSopenharmony_ci break; 104020a203aSopenharmony_ci case CATCHER_SNAPSHOT: 105020a203aSopenharmony_ci { 106020a203aSopenharmony_ci std::string path = "/data/log/eventlog/snapshot_display_"; 107020a203aSopenharmony_ci path += TimeUtil::TimestampFormatToDate(TimeUtil::GetMilliseconds() / TimeUtil::SEC_TO_MILLISEC, 108020a203aSopenharmony_ci "%Y%m%d%H%M%S"); 109020a203aSopenharmony_ci path += ".jpeg"; 110020a203aSopenharmony_ci ret = execl("/system/bin/snapshot_display", "snapshot_display", "-f", path.c_str(), nullptr); 111020a203aSopenharmony_ci } 112020a203aSopenharmony_ci break; 113020a203aSopenharmony_ci case CATCHER_SCBSESSION: 114020a203aSopenharmony_ci case CATCHER_SCBVIEWPARAM: 115020a203aSopenharmony_ci { 116020a203aSopenharmony_ci std::string cmd = (catcherType_ == CATCHER_SCBSESSION) ? "-b SCBScenePanel getContainerSession" : 117020a203aSopenharmony_ci "-b SCBScenePanel getViewParam"; 118020a203aSopenharmony_ci ret = execl("/system/bin/hidumper", "hidumper", "-s", "4606", "-a", cmd.c_str(), nullptr); 119020a203aSopenharmony_ci } 120020a203aSopenharmony_ci break; 121020a203aSopenharmony_ci default: 122020a203aSopenharmony_ci ret = DoChildProcesscatcher(writeFd); 123020a203aSopenharmony_ci break; 124020a203aSopenharmony_ci } 125020a203aSopenharmony_ci return ret; 126020a203aSopenharmony_ci} 127020a203aSopenharmony_ci 128020a203aSopenharmony_civoid ShellCatcher::DoChildProcess(int writeFd) 129020a203aSopenharmony_ci{ 130020a203aSopenharmony_ci if (writeFd < 0 || dup2(writeFd, STDOUT_FILENO) == -1 || 131020a203aSopenharmony_ci dup2(writeFd, STDIN_FILENO) == -1 || dup2(writeFd, STDERR_FILENO) == -1) { 132020a203aSopenharmony_ci HIVIEW_LOGE("dup2 writeFd fail"); 133020a203aSopenharmony_ci _exit(-1); 134020a203aSopenharmony_ci } 135020a203aSopenharmony_ci 136020a203aSopenharmony_ci int ret = -1; 137020a203aSopenharmony_ci switch (catcherType_) { 138020a203aSopenharmony_ci case CATCHER_AMS: 139020a203aSopenharmony_ci ret = execl("/system/bin/hidumper", "hidumper", "-s", "AbilityManagerService", "-a", "-a", nullptr); 140020a203aSopenharmony_ci break; 141020a203aSopenharmony_ci case CATCHER_WMS: 142020a203aSopenharmony_ci ret = execl("/system/bin/hidumper", "hidumper", "-s", "WindowManagerService", "-a", "-a", nullptr); 143020a203aSopenharmony_ci break; 144020a203aSopenharmony_ci case CATCHER_CPU: 145020a203aSopenharmony_ci ret = execl("/system/bin/hidumper", "hidumper", "--cpuusage", nullptr); 146020a203aSopenharmony_ci break; 147020a203aSopenharmony_ci case CATCHER_PMS: 148020a203aSopenharmony_ci ret = execl("/system/bin/hidumper", "hidumper", "-s", "PowerManagerService", "-a", "-s", nullptr); 149020a203aSopenharmony_ci break; 150020a203aSopenharmony_ci case CATCHER_DPMS: 151020a203aSopenharmony_ci ret = execl("/system/bin/hidumper", "hidumper", "-s", "DisplayPowerManagerService", nullptr); 152020a203aSopenharmony_ci break; 153020a203aSopenharmony_ci case CATCHER_RS: 154020a203aSopenharmony_ci ret = execl("/system/bin/hidumper", "hidumper", "-s", "RenderService", "-a", "allInfo", nullptr); 155020a203aSopenharmony_ci break; 156020a203aSopenharmony_ci case CATCHER_MMI: 157020a203aSopenharmony_ci ret = execl("/system/bin/hidumper", "hidumper", "-s", "MultimodalInput", "-a", "-w", nullptr); 158020a203aSopenharmony_ci break; 159020a203aSopenharmony_ci case CATCHER_DMS: 160020a203aSopenharmony_ci ret = execl("/system/bin/hidumper", "hidumper", "-s", "DisplayManagerService", "-a", "-a", nullptr); 161020a203aSopenharmony_ci break; 162020a203aSopenharmony_ci default: 163020a203aSopenharmony_ci ret = CaDoInChildProcesscatcher(writeFd); 164020a203aSopenharmony_ci break; 165020a203aSopenharmony_ci } 166020a203aSopenharmony_ci if (ret < 0) { 167020a203aSopenharmony_ci HIVIEW_LOGE("execl %{public}d, errno: %{public}d", ret, errno); 168020a203aSopenharmony_ci _exit(-1); 169020a203aSopenharmony_ci } 170020a203aSopenharmony_ci} 171020a203aSopenharmony_ci 172020a203aSopenharmony_civoid ShellCatcher::SetFocusWindowId(const std::string& focusWindowId) 173020a203aSopenharmony_ci{ 174020a203aSopenharmony_ci focusWindowId_ = focusWindowId; 175020a203aSopenharmony_ci} 176020a203aSopenharmony_ci 177020a203aSopenharmony_cibool ShellCatcher::ReadShellToFile(int writeFd, const std::string& cmd) 178020a203aSopenharmony_ci{ 179020a203aSopenharmony_ci int childPid = fork(); 180020a203aSopenharmony_ci if (childPid < 0) { 181020a203aSopenharmony_ci HIVIEW_LOGE("fork fail"); 182020a203aSopenharmony_ci return false; 183020a203aSopenharmony_ci } else if (childPid == 0) { 184020a203aSopenharmony_ci DoChildProcess(writeFd); 185020a203aSopenharmony_ci } else { 186020a203aSopenharmony_ci if (waitpid(childPid, nullptr, 0) != childPid) { 187020a203aSopenharmony_ci HIVIEW_LOGE("waitpid fail, pid: %{public}d, errno: %{public}d", childPid, errno); 188020a203aSopenharmony_ci return false; 189020a203aSopenharmony_ci } 190020a203aSopenharmony_ci HIVIEW_LOGI("waitpid %{public}d success", childPid); 191020a203aSopenharmony_ci } 192020a203aSopenharmony_ci return true; 193020a203aSopenharmony_ci} 194020a203aSopenharmony_ci 195020a203aSopenharmony_ciint ShellCatcher::Catch(int fd, int jsonFd) 196020a203aSopenharmony_ci{ 197020a203aSopenharmony_ci auto originSize = GetFdSize(fd); 198020a203aSopenharmony_ci if (catcherCmd_.empty()) { 199020a203aSopenharmony_ci HIVIEW_LOGE("catcherCmd empty"); 200020a203aSopenharmony_ci return -1; 201020a203aSopenharmony_ci } 202020a203aSopenharmony_ci 203020a203aSopenharmony_ci ReadShellToFile(fd, catcherCmd_); 204020a203aSopenharmony_ci logSize_ = GetFdSize(fd) - originSize; 205020a203aSopenharmony_ci return logSize_; 206020a203aSopenharmony_ci} 207020a203aSopenharmony_ci} // namespace HiviewDFX 208020a203aSopenharmony_ci} // namespace OHOS 209