1 /*
2 * Copyright (c) 2022 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 "intellisense_server.h"
17 #include <list>
18 #include <map>
19 #include <new>
20 #include <set>
21 #include <string>
22 #include <vector>
23 #include <hitrace_meter.h>
24 #include "qos_common.h"
25 #include "para_config.h"
26 #include "rtg_interface.h"
27 #include "rme_log_domain.h"
28
29 namespace OHOS {
30 namespace RME {
31 namespace {
32 static std::string configFilePath = "/system/etc/frame_aware_sched/hwrme.xml"; // need To check the exact file path.
33 constexpr int WEB_BASE_UID = 1000001;
34 constexpr int WEB_END_UID = 1099999;
35 }
36 using namespace std;
37 using namespace QosCommon;
38
39 DEFINE_RMELOG_INTELLISENSE("ueaServer-IntelliSenseServer");
40 IMPLEMENT_SINGLE_INSTANCE(IntelliSenseServer);
41
Init()42 void IntelliSenseServer::Init()
43 {
44 if (!ReadXml()) {
45 RME_LOGI("[Init]: readXml failed!");
46 return;
47 }
48 m_switch = std::stoi(m_generalPara["enable"]);
49 if (!m_switch) {
50 RME_LOGI("[Init]:xml switch close!");
51 return;
52 }
53 int ret = EnableRtg(true);
54 if (ret < 0) {
55 RME_LOGE("[Init]: enable rtg failed!");
56 return;
57 }
58 m_unsupportApp = {
59 "com.ohos.launcher",
60 "com.ohos.systemui",
61 "com.ohos.screenlock",
62 "com.ohos.wallpaper"
63 };
64 RME_LOGI("[Init]:Init rtg and readXml finish!");
65 }
66
ReadXml()67 bool IntelliSenseServer::ReadXml()
68 {
69 if (!m_needReadXml) {
70 return false;
71 }
72 m_needReadXml = false;
73 if (ParaConfig::IsXmlPrepared(configFilePath)) {
74 m_generalPara = ParaConfig::GetGeneralConfig();
75 m_subEventPara = ParaConfig::GetSubEventConfig();
76 m_fpsList = ParaConfig::GetFpsList();
77 m_renderTypeList = ParaConfig::GetRenderTypeList();
78 if (!m_generalPara.empty() && !m_subEventPara.empty() && !m_fpsList.empty() && !m_renderTypeList.empty()) {
79 m_readXmlSuc = true;
80 RME_LOGI("[ReadXml]: read slide scene xml success!");
81 return true;
82 }
83 }
84 RME_LOGE("[ReadXml]: read slide scene xml not success!");
85 return false;
86 }
87
NewForeground(int pid,int uid)88 void IntelliSenseServer::NewForeground(int pid, int uid)
89 {
90 HITRACE_METER(HITRACE_TAG_ACE);
91 int newCreatedRtg = 0;
92 for (auto iter = m_historyApp.begin(); iter != m_historyApp.end(); iter++) {
93 if (iter->GetAppUid() == uid) {
94 RME_LOGI("[ReportMessage]pid %{public}d change to foreground.", pid);
95 if (iter->GetAppState() != AppState::APP_FOREGROUND) {
96 iter->SetUiTid(pid);
97 newCreatedRtg = TryCreateRtgForApp(&*iter);
98 }
99 if (newCreatedRtg) {
100 iter->SetAppState(AppState::APP_FOREGROUND);
101 } else {
102 iter->SetAppState(AppState::APP_FOREGROUND_WITHOUT_RTG);
103 }
104 break;
105 }
106 }
107 }
108
TryCreateRtgForApp(AppInfo * app)109 int IntelliSenseServer::TryCreateRtgForApp(AppInfo *app)
110 {
111 if (!app) {
112 RME_LOGE("[TryCreateRtg]: null app!");
113 return 0;
114 }
115 int grpId = CreateNewRtgGrp(RT_PRIO, RT_NUM);
116 if (grpId <= 0) {
117 RME_LOGE("[TryCreateRtg]: createNewRtgGroup failed! grpId:%{public}d", grpId);
118 app->SetRtgrp(0);
119 return grpId;
120 }
121 app->SetRtgrp(grpId);
122 int uiTid = app->GetUiTid();
123 int renderTid = app->GetRenderTid();
124 if (uiTid > 0) {
125 AddThreadToRtg(uiTid, grpId, 0); // add ui thread
126 }
127 if (renderTid > 0) {
128 AddThreadToRtg(renderTid, grpId, 0); // add render thread
129 }
130 return grpId;
131 }
132
NewBackground(int pid)133 void IntelliSenseServer::NewBackground(int pid)
134 {
135 HITRACE_METER(HITRACE_TAG_ACE);
136 RME_LOGI("[ReportMessage]pid %{public}d change to background.", pid);
137 for (auto iter = m_historyApp.begin(); iter != m_historyApp.end(); iter++) {
138 if (iter->GetAppPid() != pid) {
139 continue;
140 }
141 iter->SetAppState(AppState::APP_BACKGROUND);
142 int grpId = iter->GetRtgrp();
143 if (grpId > 0) {
144 EndScene(grpId);
145 DestroyRtgGrp(grpId);
146 }
147 }
148 }
149
NewAppRecord(int pid,int uid)150 void IntelliSenseServer::NewAppRecord(int pid, int uid)
151 {
152 for (auto iter = m_historyApp.begin(); iter != m_historyApp.end(); iter++) {
153 if (iter->GetAppUid() == uid) {
154 RME_LOGI("[NewAppRecord]pid %{public}d already exist.", pid);
155 return;
156 }
157 }
158 AppInfo tempRecord(pid, uid);
159 tempRecord.SetAppState(AppState::APP_FOREGROUND_WITHOUT_RTG);
160 m_historyApp.push_back(tempRecord);
161 }
162
NewDiedProcess(int pid)163 void IntelliSenseServer::NewDiedProcess(int pid)
164 {
165 HITRACE_METER(HITRACE_TAG_ACE);
166 RME_LOGI("[ReportMessage]pid %{public}d died.", pid);
167 for (auto iter = m_historyApp.begin(); iter != m_historyApp.end();) {
168 if (iter->GetAppPid() == pid) {
169 int grpId = iter->GetRtgrp();
170 if (grpId > 0) {
171 EndScene(grpId);
172 DestroyRtgGrp(grpId);
173 }
174 iter = m_historyApp.erase(iter);
175 } else {
176 iter++;
177 }
178 }
179 }
180
GetRecordOfPid(int pid)181 std::list<AppInfo>::iterator IntelliSenseServer::GetRecordOfPid(int pid)
182 {
183 for (auto iter = m_historyApp.begin(); iter != m_historyApp.end(); iter++) {
184 if (iter->GetAppPid() == pid) {
185 return iter;
186 }
187 }
188 return m_historyApp.end();
189 }
190
ReportRenderThread(const int pid,const int uid,int renderTid)191 void IntelliSenseServer::ReportRenderThread(const int pid, const int uid, int renderTid)
192 {
193 if (uid >= WEB_BASE_UID && uid <= WEB_END_UID) {
194 return;
195 }
196 if (!m_switch) {
197 return;
198 }
199 HITRACE_METER(HITRACE_TAG_ACE);
200 auto record = GetRecordOfPid(pid);
201 if (record == m_historyApp.end()) {
202 RME_LOGE("Didn't find render in history app %{public}d with render %{public}d", pid, renderTid);
203 return;
204 }
205 record->SetRenderTid(renderTid);
206 int grpId = record->GetRtgrp();
207 if (grpId >= 0 && record->GetAppState() == AppState::APP_FOREGROUND) {
208 int ret = AddThreadToRtg(renderTid, grpId, 0); // add render thread
209 RME_LOGE("web test ReportRenderThread uid is %{public}d", uid);
210 if (ret != 0) {
211 RME_LOGE("[OnFore]:add render thread fail! pid:%{public}d,rtg:%{public}d!ret:%{publid}d",
212 renderTid, grpId, ret);
213 }
214 }
215 }
216
ReportWindowFocus(const int pid,const int uid,int isFocus)217 void IntelliSenseServer::ReportWindowFocus(const int pid, const int uid, int isFocus)
218 {
219 if (!m_switch) {
220 return;
221 }
222 HITRACE_METER(HITRACE_TAG_ACE);
223 switch (isFocus) {
224 case static_cast<int>(WindowState::FOCUS_YES): // isFocus: 0
225 RME_LOGI("[ReportWindowFocus]:%{public}d get focus", pid);
226 break;
227 case static_cast<int>(WindowState::FOCUS_NO): // isFocus: 1
228 RME_LOGI("[ReportWindowFocus]:%{public}d lost focus", pid);
229 break;
230 default:
231 RME_LOGI("[ReportWindowFocus]:unknown msg!");
232 break;
233 }
234 }
235
CheckCgroupState(CgroupPolicy cgroup)236 inline CgroupPolicy IntelliSenseServer::CheckCgroupState(CgroupPolicy cgroup)
237 {
238 return ((cgroup == CgroupPolicy::SP_FOREGROUND) || (cgroup == CgroupPolicy::SP_TOP_APP)) ?
239 CgroupPolicy::SP_FOREGROUND : CgroupPolicy::SP_BACKGROUND;
240 }
241
ReportCgroupChange(const int pid,const int uid,const int oldGroup,const int newGroup)242 void IntelliSenseServer::ReportCgroupChange(const int pid, const int uid, const int oldGroup, const int newGroup)
243 {
244 if (uid >= WEB_BASE_UID && uid <= WEB_END_UID) {
245 return;
246 }
247 if (!m_switch) {
248 return;
249 }
250 HITRACE_METER(HITRACE_TAG_ACE);
251 CgroupPolicy oldState = CheckCgroupState(static_cast<CgroupPolicy>(oldGroup));
252 CgroupPolicy newState = CheckCgroupState(static_cast<CgroupPolicy>(newGroup));
253 if (oldState == newState) {
254 return;
255 }
256 if (newState == CgroupPolicy::SP_BACKGROUND) {
257 RME_LOGI("CgroupChange NewBackground");
258 NewBackground(pid);
259 AuthBackground(uid);
260 } else if (newState == CgroupPolicy::SP_FOREGROUND) {
261 RME_LOGI("web test CgroupChange NewForeground uid is %{public}d", uid);
262 NewForeground(pid, uid);
263 AuthForeground(uid);
264 }
265 }
266
ReportAppInfo(const int pid,const int uid,const std::string bundleName,ThreadState state)267 void IntelliSenseServer::ReportAppInfo(const int pid, const int uid, const std::string bundleName, ThreadState state)
268 {
269 if (!m_switch) {
270 return;
271 }
272 if (state == ThreadState::CREATE) {
273 AuthForeground(uid);
274 }
275 RME_LOGI("Get app info:%{public}d %{public}d %{public}s %{public}d",
276 pid, uid, bundleName.c_str(), static_cast<int>(state));
277 }
278
ReportProcessInfo(const int pid,const int uid,const std::string bundleName,ThreadState state)279 void IntelliSenseServer::ReportProcessInfo(const int pid,
280 const int uid, const std::string bundleName, ThreadState state)
281 {
282 if (uid >= WEB_BASE_UID && uid <= WEB_END_UID) {
283 return;
284 }
285 if (!m_switch) {
286 return;
287 }
288 HITRACE_METER(HITRACE_TAG_ACE);
289 if (m_unsupportApp.find(bundleName) != m_unsupportApp.end()) {
290 return;
291 }
292 switch (state) {
293 case ThreadState::DIED:
294 RME_LOGI("ProcessInfo NewDiedProcess");
295 AuthAppKilled(uid);
296 NewDiedProcess(pid);
297 break;
298 case ThreadState::CREATE:
299 RME_LOGI("ProcessInfo NewAppRecord");
300 NewAppRecord(pid, uid);
301 break;
302 default:
303 RME_LOGI("unknown state : %{public}d", static_cast<int>(state));
304 break;
305 }
306 return;
307 }
308
SetPara(const int32_t currentFps,const int32_t currentRenderType)309 void IntelliSenseServer::SetPara(const int32_t currentFps, const int32_t currentRenderType)
310 {
311 if (!m_switch) {
312 return;
313 }
314 RME_LOGI("[SetPara]:ioctl SetPara!\n");
315 std::string key = std::to_string(currentRenderType) + " " + std::to_string(currentFps);
316 map<std::string, int> tempMap = m_subEventPara[key];
317 RME_LOGI("[SetPara]:subEventPara map size: %{public}zu", tempMap.size());
318 }
319
AuthAppKilled(int uid)320 void IntelliSenseServer::AuthAppKilled(int uid)
321 {
322 int ret = AuthDelete(uid);
323 if (ret == 0) {
324 RME_LOGI("auth_delete %{public}d success", uid);
325 } else {
326 RME_LOGE("auth_delete %{public}d failed", uid);
327 }
328 }
329
AuthForeground(int uid)330 void IntelliSenseServer::AuthForeground(int uid)
331 {
332 unsigned int flag = AF_RTG_ALL;
333 int status = AUTH_STATUS_FOREGROUND;
334 int ret = AuthEnable(uid, flag, status);
335 if (ret == 0) {
336 RME_LOGI("auth_enable %{public}d success", uid);
337 } else {
338 RME_LOGE("auth_enable %{public}d failed", uid);
339 }
340 }
341
AuthBackground(int uid)342 void IntelliSenseServer::AuthBackground(int uid)
343 {
344 int ret = AuthPause(uid);
345 if (ret == 0) {
346 RME_LOGI("auth_pause %{public}d success", uid);
347 } else {
348 RME_LOGE("auth_pause %{public}d failed", uid);
349 }
350 }
351
352 } // namespace RME
353 } // namesapce OHOS
354