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