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