1 /*
2 * Copyright (c) 2024 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 "socperf_server.h"
17 #include <file_ex.h>
18 #include <string_ex.h>
19 #include "accesstoken_kit.h"
20 #include "ipc_skeleton.h"
21 #include "parameters.h"
22 #include "system_ability_definition.h"
23 #include "tokenid_kit.h"
24 #ifdef RES_SCHED_SA_INIT
25 #include "res_sa_init.h"
26 #endif
27
28 namespace OHOS {
29 namespace SOCPERF {
30 constexpr int32_t HIVIEW_UID = 1201;
31 const bool REGISTER_RESULT =
32 SystemAbility::MakeAndRegisterAbility(DelayedSingleton<SocPerfServer>::GetInstance().get());
33 const int32_t ENG_MODE = OHOS::system::GetIntParameter("const.debuggable", 0);
34
SocPerfServer()35 SocPerfServer::SocPerfServer() : SystemAbility(SOC_PERF_SERVICE_SA_ID, true)
36 {
37 }
38
~SocPerfServer()39 SocPerfServer::~SocPerfServer()
40 {
41 }
42
OnStart()43 void SocPerfServer::OnStart()
44 {
45 if (!Publish(DelayedSingleton<SocPerfServer>::GetInstance().get())) {
46 SOC_PERF_LOGE("Register SystemAbility for SocPerf FAILED.");
47 return;
48 }
49 if (!socPerf.Init()) {
50 SOC_PERF_LOGE("SocPerf Init FAILED");
51 return;
52 }
53 }
54
OnStop()55 void SocPerfServer::OnStop()
56 {
57 }
58
AllowDump()59 bool SocPerfServer::AllowDump()
60 {
61 if (ENG_MODE == 0) {
62 SOC_PERF_LOGE("Not allow to dump SocPerfServer, mode:%{public}d", ENG_MODE);
63 return false;
64 }
65 Security::AccessToken::AccessTokenID tokenId = IPCSkeleton::GetFirstTokenID();
66 int32_t res = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, "ohos.permission.DUMP");
67 if (res != Security::AccessToken::PermissionState::PERMISSION_GRANTED) {
68 SOC_PERF_LOGE("Not allow to dump SocPerfServer, permission state:%{public}d", res);
69 return false;
70 }
71 return true;
72 }
73
Dump(int32_t fd,const std::vector<std::u16string> & args)74 int32_t SocPerfServer::Dump(int32_t fd, const std::vector<std::u16string>& args)
75 {
76 if (!AllowDump()) {
77 return ERR_PERMISSION_DENIED;
78 }
79 std::vector<std::string> argsInStr;
80 std::transform(args.begin(), args.end(), std::back_inserter(argsInStr),
81 [](const std::u16string &arg) {
82 return Str16ToStr8(arg);
83 });
84 std::string result;
85 result.append("usage: soc_perf service dump [<options>]\n")
86 .append(" 1. PerfRequest(cmdId, msg)\n")
87 .append(" 2. PerfRequestEx(cmdId, onOffTag, msg)\n")
88 .append(" 3. LimitRequest(clientId, tags, configs, msg)\n")
89 .append(" -h: show the help.\n")
90 .append(" -a: show all info.\n");
91 if (!SaveStringToFd(fd, result)) {
92 SOC_PERF_LOGE("Dump FAILED");
93 }
94 return ERR_OK;
95 }
96
PerfRequest(int32_t cmdId,const std::string & msg)97 ErrCode SocPerfServer::PerfRequest(int32_t cmdId, const std::string& msg)
98 {
99 if (!HasPerfPermission()) {
100 return ERR_PERMISSION_DENIED;
101 }
102 socPerf.PerfRequest(cmdId, msg);
103 return ERR_OK;
104 }
105
PerfRequestEx(int32_t cmdId,bool onOffTag,const std::string & msg)106 ErrCode SocPerfServer::PerfRequestEx(int32_t cmdId, bool onOffTag, const std::string& msg)
107 {
108 if (!HasPerfPermission()) {
109 return ERR_PERMISSION_DENIED;
110 }
111 socPerf.PerfRequestEx(cmdId, onOffTag, msg);
112 return ERR_OK;
113 }
114
PowerLimitBoost(bool onOffTag,const std::string & msg)115 ErrCode SocPerfServer::PowerLimitBoost(bool onOffTag, const std::string& msg)
116 {
117 if (!HasPerfPermission()) {
118 return ERR_PERMISSION_DENIED;
119 }
120 socPerf.PowerLimitBoost(onOffTag, msg);
121 return ERR_OK;
122 }
123
ThermalLimitBoost(bool onOffTag,const std::string & msg)124 ErrCode SocPerfServer::ThermalLimitBoost(bool onOffTag, const std::string& msg)
125 {
126 if (!HasPerfPermission()) {
127 return ERR_PERMISSION_DENIED;
128 }
129 socPerf.ThermalLimitBoost(onOffTag, msg);
130 return ERR_OK;
131 }
132
LimitRequest(int32_t clientId,const std::vector<int32_t> & tags,const std::vector<int64_t> & configs,const std::string & msg)133 ErrCode SocPerfServer::LimitRequest(int32_t clientId,
134 const std::vector<int32_t>& tags, const std::vector<int64_t>& configs, const std::string& msg)
135 {
136 if (!HasPerfPermission()) {
137 return ERR_PERMISSION_DENIED;
138 }
139 socPerf.LimitRequest(clientId, tags, configs, msg);
140 return ERR_OK;
141 }
142
SetRequestStatus(bool status,const std::string & msg)143 ErrCode SocPerfServer::SetRequestStatus(bool status, const std::string &msg)
144 {
145 if (!HasPerfPermission()) {
146 return ERR_PERMISSION_DENIED;
147 }
148 socPerf.SetRequestStatus(status, msg);
149 return ERR_OK;
150 }
151
SetThermalLevel(int32_t level)152 ErrCode SocPerfServer::SetThermalLevel(int32_t level)
153 {
154 if (!HasPerfPermission()) {
155 return ERR_PERMISSION_DENIED;
156 }
157 socPerf.SetThermalLevel(level);
158 return ERR_OK;
159 }
RequestDeviceMode(const std::string & mode,bool status)160 ErrCode SocPerfServer::RequestDeviceMode(const std::string& mode, bool status)
161 {
162 if (!HasPerfPermission()) {
163 return ERR_PERMISSION_DENIED;
164 }
165 socPerf.RequestDeviceMode(mode, status);
166 return ERR_OK;
167 }
168
RequestCmdIdCount(const std::string & msg,std::string & funcResult)169 ErrCode SocPerfServer::RequestCmdIdCount(const std::string& msg, std::string& funcResult)
170 {
171 int32_t callingUid = IPCSkeleton::GetCallingUid();
172 if ((ENG_MODE == 0 && callingUid != HIVIEW_UID)) {
173 SOC_PERF_LOGE("not have right to do RequestCmdIdCount");
174 return ERR_PERMISSION_DENIED;
175 }
176 if (!HasPerfPermission()) {
177 return ERR_PERMISSION_DENIED;
178 }
179 funcResult = socPerf.RequestCmdIdCount(msg);
180 return ERR_OK;
181 }
182
183 const std::string NEEDED_PERMISSION = "ohos.permission.REPORT_RESOURCE_SCHEDULE_EVENT";
184
HasPerfPermission()185 bool SocPerfServer::HasPerfPermission()
186 {
187 uint32_t accessToken = IPCSkeleton::GetCallingTokenID();
188 auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(accessToken);
189 if (int(tokenType) == OHOS::Security::AccessToken::ATokenTypeEnum::TOKEN_HAP) {
190 uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID();
191 if (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(fullTokenId)) {
192 SOC_PERF_LOGE("Invalid Permission to SocPerf");
193 return false;
194 }
195 }
196 int32_t hasPermission = Security::AccessToken::AccessTokenKit::VerifyAccessToken(accessToken, NEEDED_PERMISSION);
197 if (hasPermission != 0) {
198 SOC_PERF_LOGE("SocPerf: not have Permission");
199 return false;
200 }
201 #ifdef RES_SCHED_SA_INIT
202 int32_t clientPId = IPCSkeleton::GetCallingPid();
203 ResourceSchedule::ResSchedIpcThread::GetInstance().SetQos(clientPId);
204 #endif
205 return true;
206 }
207 } // namespace SOCPERF
208 } // namespace OHOS
209