• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "sched_controller.h"
17 
18 #include "if_system_ability_manager.h"
19 #include "iservice_registry.h"
20 #include "system_ability_definition.h"
21 #include "app_mgr_interface.h"
22 #include "app_state_observer.h"
23 #ifdef CONFIG_BGTASK_MGR
24 #include "background_task_mgr_helper.h"
25 #include "background_task_observer.h"
26 #endif
27 #include "bundle_mgr_interface.h"
28 #include "cgroup_adjuster.h"
29 #include "cgroup_event_handler.h"
30 #include "cgroup_sched_common.h"
31 #include "cgroup_sched_log.h"
32 #include "hisysevent.h"
33 #include "ressched_utils.h"
34 #include "res_type.h"
35 #include "supervisor.h"
36 #include "window_state_observer.h"
37 
38 namespace OHOS {
39 namespace ResourceSchedule {
40 namespace {
41     const std::string CG_HANDLER_THREAD = "CgroupEventHandler";
42     constexpr HiviewDFX::HiLogLabel LOG_LABEL = {LOG_CORE, LOG_TAG_DOMAIN_ID_RMS, "SchedController"};
43 }
44 
45 #ifdef CONFIG_BGTASK_MGR
46 using OHOS::BackgroundTaskMgr::BackgroundTaskMgrHelper;
47 #endif
48 
GetAppManagerInstance()49 OHOS::sptr<OHOS::AppExecFwk::IAppMgr> GetAppManagerInstance()
50 {
51     OHOS::sptr<OHOS::ISystemAbilityManager> systemAbilityManager =
52         OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
53     OHOS::sptr<OHOS::IRemoteObject> object = systemAbilityManager->GetSystemAbility(OHOS::APP_MGR_SERVICE_ID);
54     return OHOS::iface_cast<OHOS::AppExecFwk::IAppMgr>(object);
55 }
56 
GetInstance()57 SchedController& SchedController::GetInstance()
58 {
59     static SchedController instance;
60     return instance;
61 }
62 
Init()63 void SchedController::Init()
64 {
65     ChronoScope cs("Init SchedController.");
66     // Init supervisor which contains cached data for ccgroup controller.
67     InitSupervisor();
68     // Init cgroup handler thread
69     InitCgroupHandler();
70     // Init cgroup adjuster thread
71     InitCgroupAdjuster();
72 }
73 
Deinit()74 void SchedController::Deinit()
75 {
76     if (cgHandler_) {
77         cgHandler_->RemoveAllEvents();
78         cgHandler_ = nullptr;
79     }
80     if (supervisor_) {
81         supervisor_ = nullptr;
82     }
83 }
84 
UnregisterStateObservers()85 void SchedController::UnregisterStateObservers()
86 {
87     UnsubscribeAppState();
88     UnsubscribeBackgroundTask();
89     UnsubscribeWindowState();
90 }
91 
GetProcessGroup(pid_t pid)92 int SchedController::GetProcessGroup(pid_t pid)
93 {
94     if (!supervisor_) {
95         CGS_LOGE("%{public}s, supervisor nullptr.", __func__);
96         return (int32_t)(SP_DEFAULT);
97     }
98     std::shared_ptr<ProcessRecord> pr = supervisor_->FindProcessRecord(pid);
99     return pr ? (int32_t)(pr->curSchedGroup_) : (int32_t)(SP_DEFAULT);
100 }
101 
ReportAbilityStatus(int32_t saId,const std::string & deviceId,uint32_t status)102 void SchedController::ReportAbilityStatus(int32_t saId, const std::string& deviceId, uint32_t status)
103 {
104     CGS_LOGD("%{public}s sdId:%{public}d, status:%{public}d", __func__, saId, status);
105     auto handler = this->cgHandler_;
106     if (!handler) {
107         return;
108     }
109     handler->PostTask([handler, saId, deviceId, status] {
110         if (status > 0) {
111             handler->HandleAbilityAdded(saId, deviceId);
112         } else {
113             handler->HandleAbilityRemoved(saId, deviceId);
114         }
115     });
116 }
117 
DispatchResource(uint32_t resType,int64_t value,const nlohmann::json & payload)118 void SchedController::DispatchResource(uint32_t resType, int64_t value, const nlohmann::json& payload)
119 {
120     auto handler = this->cgHandler_;
121     if (!handler) {
122         return;
123     }
124     handler->PostTask([handler, resType, value, payload] {
125         switch (resType) {
126             case ResType::RES_TYPE_REPORT_MMI_PROCESS: {
127                 handler->HandleReportMMIProcess(resType, value, payload);
128                 break;
129             }
130             case ResType::RES_TYPE_REPORT_RENDER_THREAD: {
131                 handler->HandleReportRenderThread(resType, value, payload);
132                 break;
133             }
134             default: {
135                 break;
136             }
137         }
138     });
139 }
140 
GetBundleNameByUid(const int32_t uid)141 std::string SchedController::GetBundleNameByUid(const int32_t uid)
142 {
143     std::string bundleName = "";
144     OHOS::sptr<OHOS::ISystemAbilityManager> systemAbilityManager =
145         OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
146     OHOS::sptr<OHOS::IRemoteObject> object =
147         systemAbilityManager->GetSystemAbility(OHOS::BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
148     sptr<AppExecFwk::IBundleMgr> iBundleMgr = OHOS::iface_cast<OHOS::AppExecFwk::IBundleMgr>(object);
149     if (!iBundleMgr) {
150         CGS_LOGD("%{public}s null bundle manager.", __func__);
151         return bundleName;
152     }
153 
154     ErrCode ret = iBundleMgr->GetNameForUid(uid, bundleName);
155     if (ret != ERR_OK) {
156         CGS_LOGD("%{public}s get bundle name failed for %{public}d, err_code:%{public}d.", __func__, uid, ret);
157     }
158     return bundleName;
159 }
160 
InitCgroupHandler()161 inline void SchedController::InitCgroupHandler()
162 {
163     cgHandler_ = std::make_shared<CgroupEventHandler>(OHOS::AppExecFwk::EventRunner::Create(CG_HANDLER_THREAD));
164     cgHandler_->SetSupervisor(supervisor_);
165 }
166 
InitCgroupAdjuster()167 inline void SchedController::InitCgroupAdjuster()
168 {
169     CgroupAdjuster::GetInstance().InitAdjuster();
170 }
171 
InitSupervisor()172 inline void SchedController::InitSupervisor()
173 {
174     supervisor_ = std::make_shared<Supervisor>();
175 }
176 
SubscribeAppState()177 bool SchedController::SubscribeAppState()
178 {
179     if (appStateObserver_) {
180         return true;
181     }
182     sptr<OHOS::AppExecFwk::IAppMgr> appManager = GetAppManagerInstance();
183     if (!appManager) {
184         CGS_LOGE("%{public}s app manager nullptr!", __func__);
185         return false;
186     }
187     appStateObserver_ = new (std::nothrow)RmsApplicationStateObserver();
188     if (!appStateObserver_) {
189         CGS_LOGE("%{public}s allocate app state observer failed!", __func__);
190         return false;
191     }
192     int32_t err = appManager->RegisterApplicationStateObserver(appStateObserver_);
193     if (err != 0) {
194         CGS_LOGE("%{public}s register to appmanager failed. err:%{public}d", __func__, err);
195         appStateObserver_ = nullptr;
196         return false;
197     }
198     CGS_LOGI("%{public}s success.", __func__);
199     return true;
200 }
201 
UnsubscribeAppState()202 void SchedController::UnsubscribeAppState()
203 {
204     if (!appStateObserver_) {
205         return;
206     }
207 
208     sptr<OHOS::AppExecFwk::IAppMgr> appManager = GetAppManagerInstance();
209     if (appManager) {
210         int32_t err = appManager->UnregisterApplicationStateObserver(appStateObserver_);
211         if (err == 0) {
212             CGS_LOGI("%{public}s success.", __func__);
213         } else {
214             CGS_LOGE("%{public}s failed. err:%{public}d", __func__, err);
215         }
216     }
217     appStateObserver_ = nullptr;
218 }
219 
SubscribeBackgroundTask()220 bool SchedController::SubscribeBackgroundTask()
221 {
222 #ifdef CONFIG_BGTASK_MGR
223     if (backgroundTaskObserver_) {
224         return true;
225     }
226     backgroundTaskObserver_ = std::make_shared<BackgroundTaskObserver>();
227     int ret = BackgroundTaskMgrHelper::SubscribeBackgroundTask(*backgroundTaskObserver_);
228     if (ret != 0) {
229         backgroundTaskObserver_ = nullptr;
230         CGS_LOGE("%{public}s failed, err:%{public}d.", __func__, ret);
231         return false;
232     }
233     CGS_LOGI("%{public}s success.", __func__);
234 #endif
235     return true;
236 }
237 
UnsubscribeBackgroundTask()238 void SchedController::UnsubscribeBackgroundTask()
239 {
240 #ifdef CONFIG_BGTASK_MGR
241     if (!backgroundTaskObserver_) {
242         return;
243     }
244     int32_t ret = BackgroundTaskMgrHelper::UnsubscribeBackgroundTask(*backgroundTaskObserver_);
245     if (ret == 0) {
246         CGS_LOGI("%{public}s success.", __func__);
247     } else {
248         CGS_LOGE("%{public}s failed. ret:%{public}d", __func__, ret);
249     }
250     backgroundTaskObserver_ = nullptr;
251 #endif
252 }
253 
SubscribeWindowState()254 void SchedController::SubscribeWindowState()
255 {
256     if (!windowStateObserver_) {
257         windowStateObserver_ = new (std::nothrow)WindowStateObserver();
258         if (windowStateObserver_) {
259             if (OHOS::Rosen::WindowManager::GetInstance().RegisterFocusChangedListener(windowStateObserver_) != OHOS::Rosen::WMError::WM_OK) {
260                 HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::RSS, "INIT_FAULT", HiviewDFX::HiSysEvent::EventType::FAULT,
261                         "COMPONENT_NAME", "MAIN",
262                         "ERR_TYPE", "register failure",
263                         "ERR_MSG", "Register a listener of window focus change failed.");
264             }
265         }
266     }
267     if (!windowVisibilityObserver_) {
268         windowVisibilityObserver_ = new (std::nothrow)WindowVisibilityObserver();
269         if (windowVisibilityObserver_) {
270             if(OHOS::Rosen::WindowManager::GetInstance().RegisterVisibilityChangedListener(windowVisibilityObserver_) != OHOS::Rosen::WMError::WM_OK) {
271                 HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::RSS, "INIT_FAULT", HiviewDFX::HiSysEvent::EventType::FAULT,
272                         "COMPONENT_NAME", "MAIN",
273                         "ERR_TYPE", "register failure",
274                         "ERR_MSG", "Register a listener of window visibility change failed.");
275             }
276         }
277     }
278     CGS_LOGI("%{public}s success.", __func__);
279 }
280 
UnsubscribeWindowState()281 void SchedController::UnsubscribeWindowState()
282 {
283     if (windowStateObserver_) {
284         // unregister windowStateObserver_
285         OHOS::Rosen::WindowManager::GetInstance().UnregisterFocusChangedListener(windowStateObserver_);
286         windowStateObserver_ = nullptr;
287     }
288 
289     if (windowVisibilityObserver_) {
290         OHOS::Rosen::WindowManager::GetInstance().UnregisterVisibilityChangedListener(windowVisibilityObserver_);
291         windowVisibilityObserver_ = nullptr;
292     }
293 }
294 
CgroupSchedInit()295 extern "C" void CgroupSchedInit()
296 {
297     SchedController::GetInstance().Init();
298 }
299 
CgroupSchedDeinit()300 extern "C" void CgroupSchedDeinit()
301 {
302     SchedController::GetInstance().Deinit();
303     SchedController::GetInstance().UnregisterStateObservers();
304 }
305 
GetProcessGroup(pid_t pid)306 extern "C" int GetProcessGroup(pid_t pid)
307 {
308     return SchedController::GetInstance().GetProcessGroup(pid);
309 }
310 
ReportAbilityStatus(int32_t saId,const std::string & deviceId,uint32_t status)311 extern "C" void ReportAbilityStatus(int32_t saId, const std::string& deviceId, uint32_t status)
312 {
313     SchedController::GetInstance().ReportAbilityStatus(saId, deviceId, status);
314 }
315 
CgroupSchedDispatch(uint32_t resType,int64_t value,const nlohmann::json & payload)316 extern "C" void CgroupSchedDispatch(uint32_t resType, int64_t value, const nlohmann::json& payload)
317 {
318     SchedController::GetInstance().DispatchResource(resType, value, payload);
319 }
320 } // namespace ResourceSchedule
321 } // namespace OHOS
322