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