1/*
2 * Copyright (c) 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 "common/include/task_scheduler.h"
17#include "hitrace_meter.h"
18#include "window_manager_hilog.h"
19
20namespace OHOS::Rosen {
21TaskScheduler::TaskScheduler(const std::string& threadName)
22{
23    auto runner = AppExecFwk::EventRunner::Create(threadName);
24    handler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
25    pid_t tid = 0;
26    auto task = [&tid]() mutable {
27        tid = gettid();
28        TLOGI(WmsLogTag::WMS_MAIN, "get WMSTid %{public}d", static_cast<int>(tid));
29    };
30    handler_->PostSyncTask(std::move(task), "wms:setTid", AppExecFwk::EventQueue::Priority::IMMEDIATE);
31    ssmTid_ = tid;
32}
33
34std::shared_ptr<AppExecFwk::EventHandler> TaskScheduler::GetEventHandler()
35{
36    return handler_;
37}
38
39void TaskScheduler::PostAsyncTask(Task&& task, const std::string& name, int64_t delayTime)
40{
41    if (delayTime == 0 && handler_->GetEventRunner()->IsCurrentRunnerThread()) {
42        HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:%s", name.c_str());
43        task();
44        return;
45    }
46    auto localTask = [weak = weak_from_this(), task, name]() {
47        HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:%s", name.c_str());
48        task();
49        if (auto self = weak.lock()) {
50            self->ExecuteExportTask();
51        }
52    };
53    handler_->PostTask(std::move(localTask), "wms:" + name, delayTime, AppExecFwk::EventQueue::Priority::IMMEDIATE);
54}
55
56void TaskScheduler::PostVoidSyncTask(Task&& task, const std::string& name)
57{
58    if (handler_->GetEventRunner()->IsCurrentRunnerThread()) {
59        HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:%s", name.c_str());
60        task();
61        return;
62    }
63    auto localTask = [weak = weak_from_this(), task, name]() {
64        HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:%s", name.c_str());
65        task();
66        if (auto self = weak.lock()) {
67            self->ExecuteExportTask();
68        }
69    };
70    handler_->PostSyncTask(std::move(localTask), "wms:" + name, AppExecFwk::EventQueue::Priority::IMMEDIATE);
71}
72
73void TaskScheduler::PostTask(Task&& task, const std::string& name, int64_t delayTime)
74{
75    if (handler_->GetEventRunner()->IsCurrentRunnerThread()) {
76        HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:%s", name.c_str());
77        task();
78        return;
79    }
80    auto localTask = [weak = weak_from_this(), task, name]() {
81        HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:%s", name.c_str());
82        task();
83        if (auto self = weak.lock()) {
84            self->ExecuteExportTask();
85        }
86    };
87    handler_->PostTask(std::move(localTask), "wms:" + name, delayTime, AppExecFwk::EventQueue::Priority::IMMEDIATE);
88}
89
90void TaskScheduler::RemoveTask(const std::string& name)
91{
92    handler_->RemoveTask("wms:" + name);
93}
94
95void TaskScheduler::AddExportTask(std::string taskName, Task task)
96{
97    if (ssmTid_ == 0 || gettid() != ssmTid_) {
98        return task();
99    }
100    exportFuncMap_[taskName] = task;
101}
102
103void TaskScheduler::SetExportHandler(const std::shared_ptr<AppExecFwk::EventHandler>& handler)
104{
105    exportHandler_ = handler;
106}
107
108void TaskScheduler::ExecuteExportTask()
109{
110    if (exportFuncMap_.empty()) {
111        return;
112    }
113    std::shared_ptr<AppExecFwk::EventHandler> exportHandler = exportHandler_.lock();
114    if (!exportHandler) {
115        return;
116    }
117    auto task = [funcMap = std::move(exportFuncMap_)]() {
118        for (auto iter = funcMap.begin(); iter != funcMap.end(); iter++) {
119            HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:%s", iter->first.c_str());
120            iter->second();
121        }
122    };
123    exportFuncMap_.clear();
124    exportHandler->PostTask(task, "wms:exportTask");
125}
126
127void StartTraceForSyncTask(std::string name)
128{
129    StartTraceArgs(HITRACE_TAG_WINDOW_MANAGER, "ssm:%s", name.c_str());
130}
131void FinishTraceForSyncTask()
132{
133    FinishTrace(HITRACE_TAG_WINDOW_MANAGER);
134}
135} // namespace OHOS::Rosen