• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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