1 /*
2 * Copyright (c) 2022-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 <cstdint>
17 #include "res_sched_service.h"
18 #include <file_ex.h>
19 #include <parameters.h>
20 #include <string_ex.h>
21 #include "accesstoken_kit.h"
22 #include "ipc_skeleton.h"
23 #include "plugin_mgr.h"
24 #include "res_sched_errors.h"
25 #include "res_sched_log.h"
26 #include "res_sched_mgr.h"
27 #include "tokenid_kit.h"
28 #include "sched_controller.h"
29 #include "supervisor.h"
30
31 namespace OHOS {
32 namespace ResourceSchedule {
33 using namespace OHOS::Security;
34 namespace {
35 constexpr int32_t DUMP_OPTION = 0;
36 constexpr int32_t DUMP_PARAM_INDEX = 1;
37 const int32_t ENG_MODE = OHOS::system::GetIntParameter("const.debuggable", 0);
38 }
39
ReportData(uint32_t resType,int64_t value,const nlohmann::json & payload)40 void ResSchedService::ReportData(uint32_t resType, int64_t value, const nlohmann::json& payload)
41 {
42 RESSCHED_LOGI("ResSchedService::ReportData from ipc receive data resType = %{public}u, value = %{public}lld.",
43 resType, (long long)value);
44 const nlohmann::json* payloadP = &payload;
45 int32_t callingUid = IPCSkeleton::GetCallingUid();
46 nlohmann::json* payloadM = const_cast<nlohmann::json*>(payloadP);
47 (*payloadM)["callingUid"] = std::to_string(callingUid);
48 ResSchedMgr::GetInstance().ReportData(resType, value, *payloadM);
49 }
50
KillProcess(const nlohmann::json & payload)51 int32_t ResSchedService::KillProcess(const nlohmann::json& payload)
52 {
53 return ResSchedMgr::GetInstance().KillProcessByClient(payload);
54
55 }
56
AllowDump()57 bool ResSchedService::AllowDump()
58 {
59 if (ENG_MODE == 0) {
60 RESSCHED_LOGE("Not eng mode");
61 return false;
62 }
63 Security::AccessToken::AccessTokenID tokenId = IPCSkeleton::GetCallingTokenID();
64 int32_t ret = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, "ohos.permission.DUMP");
65 if (ret != Security::AccessToken::PermissionState::PERMISSION_GRANTED) {
66 RESSCHED_LOGE("CheckPermission failed");
67 return false;
68 }
69 return true;
70 }
71
Dump(int32_t fd,const std::vector<std::u16string> & args)72 int32_t ResSchedService::Dump(int32_t fd, const std::vector<std::u16string>& args)
73 {
74 if (!AllowDump()) {
75 return ERR_RES_SCHED_PERMISSION_DENIED;
76 }
77 RESSCHED_LOGI("%{public}s Dump service.", __func__);
78 std::vector<std::string> argsInStr;
79 std::transform(args.begin(), args.end(), std::back_inserter(argsInStr),
80 [](const std::u16string &arg) {
81 std::string ret = Str16ToStr8(arg);
82 RESSCHED_LOGI("%{public}s arg: %{public}s.", __func__, ret.c_str());
83 return ret;
84 });
85 std::string result;
86 if (argsInStr.size() == 0) {
87 // hidumper -s said '-h'
88 DumpUsage(result);
89 } else if (argsInStr.size() == DUMP_OPTION + 1) {
90 // hidumper -s said '-h' or hidumper -s said '-a'
91 if (argsInStr[DUMP_OPTION] == "-h") {
92 DumpUsage(result);
93 } else if (argsInStr[DUMP_OPTION] == "-a") {
94 DumpAllInfo(result);
95 } else if (argsInStr[DUMP_OPTION] == "-p") {
96 PluginMgr::GetInstance().DumpAllPlugin(result);
97 } else if (argsInStr[DUMP_OPTION] == "getRunningLockInfo") {
98 DumpProcessRunningLock(result);
99 } else if (argsInStr[DUMP_OPTION] == "getProcessEventInfo") {
100 DumpProcessEventState(result);
101 } else if (argsInStr[DUMP_OPTION] == "getProcessWindowInfo") {
102 DumpProcessWindowInfo(result);
103 } else {
104 result.append("Error params.");
105 }
106 } else if (argsInStr.size() >= DUMP_PARAM_INDEX + 1) {
107 if (argsInStr[DUMP_OPTION] == "-p") {
108 std::vector<std::string> argsInStrToPlugin;
109 argsInStrToPlugin.assign(argsInStr.begin() + DUMP_PARAM_INDEX + 1, argsInStr.end());
110 PluginMgr::GetInstance().DumpOnePlugin(result, argsInStr[DUMP_PARAM_INDEX], argsInStrToPlugin);
111 }
112 }
113
114 if (!SaveStringToFd(fd, result)) {
115 RESSCHED_LOGE("%{public}s save to fd failed.", __func__);
116 }
117 return ERR_OK;
118 }
119
DumpProcessRunningLock(std::string & result)120 void ResSchedService::DumpProcessRunningLock(std::string &result)
121 {
122 auto supervisor = SchedController::GetInstance().GetSupervisor();
123 if (supervisor == nullptr) {
124 result.append("get supervisor failed");
125 return;
126 }
127
128 std::map<int32_t, std::shared_ptr<Application>> uidMap = supervisor->GetUidsMap();
129 for (auto it = uidMap.begin(); it != uidMap.end(); it++) {
130 int32_t uid = it->first;
131 std::shared_ptr<Application> app = it->second;
132 std::map<pid_t, std::shared_ptr<ProcessRecord>> pidMap = app->GetPidsMap();
133 for (auto pidIt = pidMap.begin(); pidIt != pidMap.end(); pidIt++) {
134 int32_t pid = pidIt->first;
135 std::shared_ptr<ProcessRecord> process = pidIt->second;
136 for (auto lockIt = process->runningLockState_.begin();
137 lockIt != process->runningLockState_.end(); lockIt++) {
138 uint32_t lockType = lockIt->first;
139 bool lockState = lockIt->second;
140 result.append("uid:").append(ToString(uid))
141 .append(", pid:").append(ToString(pid))
142 .append(", lockType:").append(ToString(lockType))
143 .append(", lockState:").append(ToString(lockState)).append("\n");
144 }
145 }
146 }
147 }
148
DumpProcessWindowInfo(std::string & result)149 void ResSchedService::DumpProcessWindowInfo(std::string &result)
150 {
151 auto supervisor = SchedController::GetInstance().GetSupervisor();
152 if (supervisor == nullptr) {
153 result.append("get supervisor failed");
154 return;
155 }
156
157 std::map<int32_t, std::shared_ptr<Application>> uidMap = supervisor->GetUidsMap();
158 for (auto it = uidMap.begin(); it != uidMap.end(); it++) {
159 int32_t uid = it->first;
160 std::shared_ptr<Application> app = it->second;
161 std::map<pid_t, std::shared_ptr<ProcessRecord>> pidMap = app->GetPidsMap();
162 std::string bundleName = app->GetName();
163 for (auto pidIt = pidMap.begin(); pidIt != pidMap.end(); pidIt++) {
164 int32_t pid = pidIt->first;
165 std::shared_ptr<ProcessRecord> process = pidIt->second;
166 if (process->windows_.size() == 0) {
167 continue;
168 }
169 result.append("uid:").append(ToString(uid))
170 .append(", pid:").append(ToString(pid))
171 .append(", bundleName:").append(bundleName)
172 .append(", processDrawingState:").append(ToString(process->processDrawingState_))
173 .append(", windowInfo:").append("\n");
174 for (auto &windows : process->windows_) {
175 result.append(" windowId:").append(ToString(windows->windowId_))
176 .append(", visibilityState:").append(ToString(windows->visibilityState_))
177 .append(", isVisible:").append(ToString(windows->isVisible_))
178 .append(", isFocus:").append(ToString(windows->isFocused_)).append("\n");
179 }
180 }
181 }
182 }
183
DumpProcessEventState(std::string & result)184 void ResSchedService::DumpProcessEventState(std::string &result)
185 {
186 auto supervisor = SchedController::GetInstance().GetSupervisor();
187 if (supervisor == nullptr) {
188 result.append("get supervisor failed");
189 return;
190 }
191
192 std::map<int32_t, std::shared_ptr<Application>> uidMap = supervisor->GetUidsMap();
193 for (auto it = uidMap.begin(); it != uidMap.end(); it++) {
194 int32_t uid = it->first;
195 std::shared_ptr<Application> app = it->second;
196 std::map<pid_t, std::shared_ptr<ProcessRecord>> pidMap = app->GetPidsMap();
197 for (auto pidIt = pidMap.begin(); pidIt != pidMap.end(); pidIt++) {
198 int32_t pid = pidIt->first;
199 std::shared_ptr<ProcessRecord> process = pidIt->second;
200 if (process->isRenderProcess_) {
201 continue;
202 }
203 result.append("uid:").append(ToString(uid))
204 .append(", pid:").append(ToString(pid))
205 .append(", processState:").append(ToString(process->processState_))
206 .append(", napState:").append(ToString(process->isNapState_))
207 .append(", processDrawingState:").append(ToString(process->processDrawingState_))
208 .append(", mmiState:").append(ToString(process->mmiStatus_))
209 .append(", camearaStatus:").append(ToString(process->cameraState_))
210 .append(", bluetoothStatus:").append(ToString(process->bluetoothState_))
211 .append(", wifiStatus:").append(ToString(process->wifiState_)).append("\n")
212 .append(", screenCaptureStatus:").append(ToString(process->screenCaptureState_)).append("\n");
213 }
214 }
215 }
216
DumpUsage(std::string & result)217 void ResSchedService::DumpUsage(std::string &result)
218 {
219 result.append("usage: resource schedule service dump [<options>]\n")
220 .append(" -h: show the help.\n")
221 .append(" -a: show all info.\n")
222 .append(" -p: show the all plugin info.\n")
223 .append(" -p (plugin name): show one plugin info.\n");
224 PluginMgr::GetInstance().DumpHelpFromPlugin(result);
225 }
226
DumpAllInfo(std::string & result)227 void ResSchedService::DumpAllInfo(std::string &result)
228 {
229 result.append("================Resource Schedule Service Infos================\n");
230 PluginMgr::GetInstance().DumpAllPlugin(result);
231 }
232 } // namespace ResourceSchedule
233 } // namespace OHOS
234
235