• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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 #include "app_startup_scene_rec.h"
24 #ifdef CONFIG_BGTASK_MGR
25 #include "background_task_mgr_helper.h"
26 #include "background_task_observer.h"
27 #endif
28 #include "bundle_mgr_interface.h"
29 #include "cgroup_adjuster.h"
30 #include "cgroup_event_handler.h"
31 #include "cgroup_sched_common.h"
32 #include "cgroup_sched_log.h"
33 #include "hisysevent.h"
34 #include "ressched_utils.h"
35 #include "res_type.h"
36 #include "supervisor.h"
37 #include "window_state_observer.h"
38 #ifdef POWER_MANAGER_ENABLE
39 #include "power_mgr_client.h"
40 #endif
41 
42 #undef LOG_TAG
43 #define LOG_TAG "SchedController"
44 
45 namespace OHOS {
46 namespace ResourceSchedule {
47 namespace {
48     const std::string CG_HANDLER_QUEUE = "CgroupEventHandlerQueue";
49 }
50 
51 #ifdef CONFIG_BGTASK_MGR
52 using OHOS::BackgroundTaskMgr::BackgroundTaskMgrHelper;
53 #endif
54 
GetAppManagerInstance()55 OHOS::sptr<OHOS::AppExecFwk::IAppMgr> GetAppManagerInstance()
56 {
57     OHOS::sptr<OHOS::ISystemAbilityManager> systemAbilityManager =
58         OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
59     OHOS::sptr<OHOS::IRemoteObject> object = systemAbilityManager->GetSystemAbility(OHOS::APP_MGR_SERVICE_ID);
60     return OHOS::iface_cast<OHOS::AppExecFwk::IAppMgr>(object);
61 }
62 
GetInstance()63 SchedController& SchedController::GetInstance()
64 {
65     static SchedController instance;
66     return instance;
67 }
68 
Init()69 void SchedController::Init()
70 {
71     ChronoScope cs("Init SchedController.");
72     // Init supervisor which contains cached data for ccgroup controller.
73     InitSupervisor();
74     // init dispatch resource function map
75     InitDispatchResFuncMap();
76     // Init cgroup handler thread
77     InitCgroupHandler();
78     // Init cgroup adjuster thread
79     InitCgroupAdjuster();
80     InitAppStartupSceneRec();
81 }
82 
Deinit()83 void SchedController::Deinit()
84 {
85     if (cgHandler_) {
86         cgHandler_ = nullptr;
87     }
88     if (supervisor_) {
89         supervisor_ = nullptr;
90     }
91     DeinitAppStartupSceneRec();
92 }
93 
94 
UnregisterStateObservers()95 void SchedController::UnregisterStateObservers()
96 {
97     UnsubscribeAppState();
98     UnsubscribeBackgroundTask();
99     UnsubscribeWindowState();
100 }
101 
GetProcessGroup(pid_t pid)102 int SchedController::GetProcessGroup(pid_t pid)
103 {
104     if (!supervisor_) {
105         CGS_LOGE("%{public}s, supervisor nullptr.", __func__);
106         return (int32_t)(SP_DEFAULT);
107     }
108     std::shared_ptr<ProcessRecord> pr = supervisor_->FindProcessRecord(pid);
109     return pr ? (int32_t)(pr->curSchedGroup_) : (int32_t)(SP_DEFAULT);
110 }
111 
ReportAbilityStatus(int32_t saId,const std::string & deviceId,uint32_t status)112 void SchedController::ReportAbilityStatus(int32_t saId, const std::string& deviceId, uint32_t status)
113 {
114     CGS_LOGD("%{public}s sdId:%{public}d, status:%{public}d", __func__, saId, status);
115     auto handler = this->cgHandler_;
116     if (!handler) {
117         return;
118     }
119     handler->PostTask([handler, saId, deviceId, status] {
120         if (status > 0) {
121             handler->HandleAbilityAdded(saId, deviceId);
122         } else {
123             handler->HandleAbilityRemoved(saId, deviceId);
124         }
125     });
126 }
127 
DispatchResource(uint32_t resType,int64_t value,const nlohmann::json & payload)128 void SchedController::DispatchResource(uint32_t resType, int64_t value, const nlohmann::json& payload)
129 {
130     auto handler = this->cgHandler_;
131     if (!handler) {
132         return;
133     }
134 
135     auto iter = dispatchResFuncMap_.find(resType);
136     if (iter == dispatchResFuncMap_.end()) {
137         DispatchOtherResource(resType, value, payload);
138         return;
139     }
140     handler->PostTask([func = iter->second, handler, resType, value, payload] {
141         func(handler, resType, value, payload);
142     });
143     DispatchOtherResource(resType, value, payload);
144 }
145 
DispatchOtherResource(uint32_t resType,int64_t value,const nlohmann::json & payload)146 void SchedController::DispatchOtherResource(uint32_t resType, int64_t value, const nlohmann::json& payload)
147 {
148     auto handler = this->cgHandler_;
149     if (!handler) {
150         return;
151     }
152     handler->PostTask([handler, resType, value, payload] {
153         switch (resType) {
154             case ResType::RES_TYPE_REPORT_CAMERA_STATE:
155             case ResType::RES_TYPE_BLUETOOTH_A2DP_CONNECT_STATE_CHANGE:
156             case ResType::RES_TYPE_WIFI_CONNECT_STATE_CHANGE:
157             case ResType::RES_TYPE_MMI_INPUT_STATE: {
158                 handler->HandleReportHisysEvent(resType, value, payload);
159                 break;
160             }
161             case ResType::RES_TYPE_REPORT_SCREEN_CAPTURE: {
162                 handler->HandleReportScreenCaptureEvent(resType, value, payload);
163                 break;
164             }
165             case ResType::RES_TYPE_AV_CODEC_STATE: {
166                 handler->HandleReportAvCodecEvent(resType, value, payload);
167                 break;
168             }
169             default: {
170                 break;
171             }
172         }
173     });
174     ResSchedUtils::GetInstance().DispatchResourceExt(resType, value, payload);
175 }
176 
GetBundleNameByUid(const int32_t uid)177 std::string SchedController::GetBundleNameByUid(const int32_t uid)
178 {
179     std::string bundleName = "";
180     OHOS::sptr<OHOS::ISystemAbilityManager> systemAbilityManager =
181         OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
182     OHOS::sptr<OHOS::IRemoteObject> object =
183         systemAbilityManager->GetSystemAbility(OHOS::BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
184     sptr<AppExecFwk::IBundleMgr> iBundleMgr = OHOS::iface_cast<OHOS::AppExecFwk::IBundleMgr>(object);
185     if (!iBundleMgr) {
186         CGS_LOGD("%{public}s null bundle manager.", __func__);
187         return bundleName;
188     }
189 
190     ErrCode ret = iBundleMgr->GetNameForUid(uid, bundleName);
191     if (ret != ERR_OK) {
192         CGS_LOGD("%{public}s get bundle name failed for %{public}d, err_code:%{public}d.", __func__, uid, ret);
193     }
194     return bundleName;
195 }
196 
InitCgroupHandler()197 inline void SchedController::InitCgroupHandler()
198 {
199     cgHandler_ = std::make_shared<CgroupEventHandler>(CG_HANDLER_QUEUE);
200     cgHandler_->SetSupervisor(supervisor_);
201 }
202 
InitCgroupAdjuster()203 inline void SchedController::InitCgroupAdjuster()
204 {
205     CgroupAdjuster::GetInstance().InitAdjuster();
206 }
207 
InitSupervisor()208 inline void SchedController::InitSupervisor()
209 {
210     supervisor_ = std::make_shared<Supervisor>();
211 }
212 
InitDispatchResFuncMap()213 void SchedController::InitDispatchResFuncMap()
214 {
215     dispatchResFuncMap_ = {
216         { ResType::RES_TYPE_REPORT_MMI_PROCESS, [](std::shared_ptr<CgroupEventHandler> handler,
217             uint32_t resType, int64_t value, const nlohmann::json& payload)
218             { handler->HandleReportMMIProcess(resType, value, payload); } },
219         { ResType::RES_TYPE_REPORT_RENDER_THREAD, [](std::shared_ptr<CgroupEventHandler> handler,
220             uint32_t resType, int64_t value, const nlohmann::json& payload)
221             { handler->HandleReportRenderThread(resType, value, payload); } },
222         { ResType::RES_TYPE_REPORT_KEY_THREAD, [](std::shared_ptr<CgroupEventHandler> handler,
223             uint32_t resType, int64_t value, const nlohmann::json& payload)
224             { handler->HandleReportKeyThread(resType, value, payload); } },
225         { ResType::RES_TYPE_REPORT_WINDOW_STATE, [](std::shared_ptr<CgroupEventHandler> handler,
226             uint32_t resType, int64_t value, const nlohmann::json& payload)
227             { handler->HandleReportWindowState(resType, value, payload); } },
228         { ResType::RES_TYPE_WEBVIEW_AUDIO_STATUS_CHANGE, [](std::shared_ptr<CgroupEventHandler> handler,
229             uint32_t resType, int64_t value, const nlohmann::json& payload)
230             { handler->HandleReportWebviewAudioState(resType, value, payload); } },
231         { ResType::RES_TYPE_AUDIO_RENDER_STATE_CHANGE, [](std::shared_ptr<CgroupEventHandler> handler,
232             uint32_t resType, int64_t value, const nlohmann::json& payload)
233             { handler->HandleReportAudioState(resType, value, payload); } },
234         { ResType::RES_TYPE_RUNNINGLOCK_STATE, [](std::shared_ptr<CgroupEventHandler> handler,
235             uint32_t resType, int64_t value, const nlohmann::json& payload)
236             { handler->HandleReportRunningLockEvent(resType, value, payload); } },
237         { ResType::RES_TYPE_REPORT_SCENE_BOARD, [](std::shared_ptr<CgroupEventHandler> handler,
238             uint32_t resType, int64_t value, const nlohmann::json& payload)
239             { handler->HandleSceneBoardState(resType, value, payload); } },
240         { ResType::RES_TYPE_WEBVIEW_SCREEN_CAPTURE, [](std::shared_ptr<CgroupEventHandler> handler,
241             uint32_t resType, int64_t value, const nlohmann::json& payload)
242             { handler->HandleWebviewScreenCapture(resType, value, payload); } },
243         { ResType::RES_TYPE_WEBVIEW_VIDEO_STATUS_CHANGE, [](std::shared_ptr<CgroupEventHandler> handler,
244             uint32_t resType, int64_t value, const nlohmann::json& payload)
245             { handler->HandleReportWebviewVideoState(resType, value, payload); } },
246     };
247 }
248 
InitAppStartupSceneRec()249 inline void SchedController::InitAppStartupSceneRec()
250 {
251     AppStartupSceneRec::GetInstance().Init();
252 }
253 
DeinitAppStartupSceneRec()254 inline void SchedController::DeinitAppStartupSceneRec()
255 {
256     AppStartupSceneRec::GetInstance().Deinit();
257 }
258 
SubscribeAppState()259 bool SchedController::SubscribeAppState()
260 {
261     if (appStateObserver_) {
262         return true;
263     }
264     sptr<OHOS::AppExecFwk::IAppMgr> appManager = GetAppManagerInstance();
265     if (!appManager) {
266         CGS_LOGE("%{public}s app manager nullptr!", __func__);
267         return false;
268     }
269     appStateObserver_ = new (std::nothrow)RmsApplicationStateObserver();
270     if (!appStateObserver_) {
271         CGS_LOGE("%{public}s allocate app state observer failed!", __func__);
272         return false;
273     }
274     int32_t err = appManager->RegisterApplicationStateObserver(appStateObserver_);
275     if (err != 0) {
276         CGS_LOGE("%{public}s register to appmanager failed. err:%{public}d", __func__, err);
277         appStateObserver_ = nullptr;
278         return false;
279     }
280     CGS_LOGI("%{public}s success.", __func__);
281     return true;
282 }
283 
UnsubscribeAppState()284 void SchedController::UnsubscribeAppState()
285 {
286     if (!appStateObserver_) {
287         return;
288     }
289 
290     sptr<OHOS::AppExecFwk::IAppMgr> appManager = GetAppManagerInstance();
291     if (appManager) {
292         int32_t err = appManager->UnregisterApplicationStateObserver(appStateObserver_);
293         if (err == 0) {
294             CGS_LOGI("%{public}s success.", __func__);
295         } else {
296             CGS_LOGE("%{public}s failed. err:%{public}d", __func__, err);
297         }
298     }
299     appStateObserver_ = nullptr;
300 }
301 
SubscribeBackgroundTask()302 bool SchedController::SubscribeBackgroundTask()
303 {
304 #ifdef CONFIG_BGTASK_MGR
305     if (isBgtaskSubscribed_) {
306         return true;
307     }
308     if (!backgroundTaskObserver_) {
309         backgroundTaskObserver_ = std::make_shared<BackgroundTaskObserver>();
310     }
311     int ret = BackgroundTaskMgrHelper::SubscribeBackgroundTask(*backgroundTaskObserver_);
312     if (ret != 0) {
313         CGS_LOGE("%{public}s failed, err:%{public}d.", __func__, ret);
314         return false;
315     }
316     isBgtaskSubscribed_ = true;
317     CGS_LOGI("%{public}s success.", __func__);
318 #endif
319     return true;
320 }
321 
UnsubscribeBackgroundTask()322 void SchedController::UnsubscribeBackgroundTask()
323 {
324 #ifdef CONFIG_BGTASK_MGR
325     if (!isBgtaskSubscribed_ || !backgroundTaskObserver_) {
326         return;
327     }
328     int32_t ret = BackgroundTaskMgrHelper::UnsubscribeBackgroundTask(*backgroundTaskObserver_);
329     if (ret == 0) {
330         CGS_LOGI("%{public}s success.", __func__);
331     } else {
332         CGS_LOGE("%{public}s failed. ret:%{public}d", __func__, ret);
333     }
334     isBgtaskSubscribed_ = false;
335 #endif
336 }
337 
SubscribeWindowState()338 void SchedController::SubscribeWindowState()
339 {
340     if (!windowStateObserver_) {
341         windowStateObserver_ = new (std::nothrow)WindowStateObserver();
342         if (windowStateObserver_) {
343             OHOS::Rosen::WMError ret =
344                 OHOS::Rosen::WindowManagerLite::GetInstance().RegisterFocusChangedListener(windowStateObserver_);
345             if (ret != OHOS::Rosen::WMError::WM_OK) {
346                 HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::RSS, "INIT_FAULT",
347                                 HiviewDFX::HiSysEvent::EventType::FAULT,
348                                 "COMPONENT_NAME", "MAIN",
349 								"ERR_TYPE", "register failure",
350                                 "ERR_MSG", "Register a listener of window focus change failed.");
351             }
352         }
353     }
354     if (!windowVisibilityObserver_) {
355         windowVisibilityObserver_ = new (std::nothrow)WindowVisibilityObserver();
356         if (windowVisibilityObserver_) {
357             OHOS::Rosen::WMError ret = OHOS::Rosen::WindowManagerLite::GetInstance().
358 				RegisterVisibilityChangedListener(windowVisibilityObserver_);
359             if (ret != OHOS::Rosen::WMError::WM_OK) {
360                 HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::RSS, "INIT_FAULT",
361                                 HiviewDFX::HiSysEvent::EventType::FAULT,
362                                 "COMPONENT_NAME", "MAIN",
363                                 "ERR_TYPE", "register failure",
364                                 "ERR_MSG", "Register a listener of window visibility change failed.");
365             }
366         }
367     }
368     if (!windowDrawingContentObserver_) {
369         windowDrawingContentObserver_ = new (std::nothrow)WindowDrawingContentObserver();
370         if (windowDrawingContentObserver_) {
371             if (OHOS::Rosen::WindowManagerLite::GetInstance().
372                 RegisterDrawingContentChangedListener(windowDrawingContentObserver_) != OHOS::Rosen::WMError::WM_OK) {
373                     HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::RSS, "INIT_FAULT",
374                                     HiviewDFX::HiSysEvent::EventType::FAULT,
375                                     "COMPONENT_NAME", "MAIN", "ERR_TYPE", "register failure",
376                                     "ERR_MSG", "Register a listener of window draw content change failed.");
377             }
378         }
379     }
380     SubscribeWindowModeChange();
381     CGS_LOGI("%{public}s success.", __func__);
382 }
383 
SubscribeWindowModeChange()384 void SchedController::SubscribeWindowModeChange()
385 {
386     if (!windowModeObserver_) {
387         windowModeObserver_ = new (std::nothrow)WindowModeObserver();
388         if (windowModeObserver_) {
389             if (OHOS::Rosen::WindowManagerLite::GetInstance().
390                 RegisterWindowModeChangedListener(windowModeObserver_) != OHOS::Rosen::WMError::WM_OK) {
391                     HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::RSS,
392                                     "INIT_FAULT", HiviewDFX::HiSysEvent::EventType::FAULT,
393                                     "COMPONENT_NAME", "MAIN", "ERR_TYPE", "register failure",
394                                     "ERR_MSG", "Register a listener of window mode content change failed.");
395             }
396         }
397     }
398 }
399 
UnsubscribeWindowState()400 void SchedController::UnsubscribeWindowState()
401 {
402     if (windowStateObserver_) {
403         // unregister windowStateObserver_
404         OHOS::Rosen::WindowManagerLite::GetInstance().UnregisterFocusChangedListener(windowStateObserver_);
405         windowStateObserver_ = nullptr;
406     }
407 
408     if (windowVisibilityObserver_) {
409         OHOS::Rosen::WindowManagerLite::GetInstance().UnregisterVisibilityChangedListener(windowVisibilityObserver_);
410         windowVisibilityObserver_ = nullptr;
411     }
412 
413     if (windowDrawingContentObserver_) {
414         OHOS::Rosen::WindowManagerLite::GetInstance().
415             UnregisterDrawingContentChangedListener(windowDrawingContentObserver_);
416         windowDrawingContentObserver_ = nullptr;
417     }
418     UnsubscribeWindowModeChange();
419 }
420 
UnsubscribeWindowModeChange()421 void SchedController::UnsubscribeWindowModeChange()
422 {
423     if (windowModeObserver_) {
424         OHOS::Rosen::WindowManagerLite::GetInstance().
425             UnregisterWindowModeChangedListener(windowModeObserver_);
426         windowModeObserver_ = nullptr;
427     }
428     CGS_LOGI("UnsubscribeWindowModeChange success");
429 }
430 
431 #ifdef POWER_MANAGER_ENABLE
GetRunningLockState()432 void SchedController::GetRunningLockState()
433 {
434     if (!supervisor_) {
435         CGS_LOGE("%{public}s, supervisor nullptr.", __func__);
436         return;
437     }
438     std::map<std::string, PowerMgr::RunningLockInfo> runningLockLists;
439     bool ret = PowerMgr::PowerMgrClient::GetInstance().QueryRunningLockLists(runningLockLists);
440     if (!ret) {
441         CGS_LOGE("%{public}s get running lock list failed.", __func__);
442         return;
443     }
444     for (auto it = runningLockLists.begin(); it != runningLockLists.end(); it++) {
445         std::string bundleName = it->first;
446         PowerMgr::RunningLockInfo lockInfo = it->second;
447         std::shared_ptr<Application> app = supervisor_->GetAppRecordNonNull(lockInfo.uid);
448         std::shared_ptr<ProcessRecord> procRecord = app->GetProcessRecordNonNull(lockInfo.pid);
449         uint32_t key = static_cast<uint32_t>(lockInfo.type);
450         procRecord->runningLockState_[key] = true;
451     }
452 }
453 #endif
454 
CgroupSchedInit()455 extern "C" void CgroupSchedInit()
456 {
457     SchedController::GetInstance().Init();
458 }
459 
CgroupSchedDeinit()460 extern "C" void CgroupSchedDeinit()
461 {
462     SchedController::GetInstance().Deinit();
463     SchedController::GetInstance().UnregisterStateObservers();
464 }
465 
GetProcessGroup(pid_t pid)466 extern "C" int GetProcessGroup(pid_t pid)
467 {
468     return SchedController::GetInstance().GetProcessGroup(pid);
469 }
470 
ReportAbilityStatus(int32_t saId,const std::string & deviceId,uint32_t status)471 extern "C" void ReportAbilityStatus(int32_t saId, const std::string& deviceId, uint32_t status)
472 {
473     SchedController::GetInstance().ReportAbilityStatus(saId, deviceId, status);
474 }
475 
CgroupSchedDispatch(uint32_t resType,int64_t value,const nlohmann::json & payload)476 extern "C" void CgroupSchedDispatch(uint32_t resType, int64_t value, const nlohmann::json& payload)
477 {
478     SchedController::GetInstance().DispatchResource(resType, value, payload);
479 }
480 } // namespace ResourceSchedule
481 } // namespace OHOS
482