1 /*
2 * Copyright (c) 2025 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 "ui/rs_ui_context.h"
17
18 #include "command/rs_node_command.h"
19 #include "modifier/rs_modifier_manager_map.h"
20 #include "platform/common/rs_log.h"
21 #include "ui/rs_ui_context_manager.h"
22
23 namespace OHOS {
24 namespace Rosen {
RSUIContext(uint64_t token)25 RSUIContext::RSUIContext(uint64_t token) : token_(token)
26 {
27 rsTransactionHandler_ = std::make_shared<RSTransactionHandler>(token);
28 rsSyncTransactionHandler_ = std::shared_ptr<RSSyncTransactionHandler>(new RSSyncTransactionHandler());
29 rsSyncTransactionHandler_->SetTransactionHandler(rsTransactionHandler_);
30 }
31
RSUIContext()32 RSUIContext::RSUIContext() : RSUIContext(0) {}
33
~RSUIContext()34 RSUIContext::~RSUIContext() {}
35
GetRSImplicitAnimator()36 const std::shared_ptr<RSImplicitAnimator> RSUIContext::GetRSImplicitAnimator()
37 {
38 std::lock_guard<std::mutex> lock(implicitAnimatorMutex_);
39 auto it = rsImplicitAnimators_.find(gettid());
40 if (it != rsImplicitAnimators_.end()) {
41 return it->second;
42 } else {
43 if (rsImplicitAnimators_.size() > 0) {
44 RS_LOGI_LIMIT("Too many threads are using the same animator");
45 }
46 auto rsImplicitAnimator = std::make_shared<RSImplicitAnimator>();
47 rsImplicitAnimator->SetRSUIContext(weak_from_this());
48 rsImplicitAnimators_.emplace(gettid(), rsImplicitAnimator);
49 return rsImplicitAnimator;
50 }
51 }
52
GetRSModifierManager()53 const std::shared_ptr<RSModifierManager> RSUIContext::GetRSModifierManager()
54 {
55 if (rsModifierManager_ == nullptr) {
56 rsModifierManager_ = std::make_shared<RSModifierManager>();
57 }
58 return rsModifierManager_;
59 }
60
AnimationCallback(AnimationId animationId,AnimationCallbackEvent event)61 bool RSUIContext::AnimationCallback(AnimationId animationId, AnimationCallbackEvent event)
62 {
63 std::shared_ptr<RSAnimation> animation = nullptr;
64 {
65 std::unique_lock<std::recursive_mutex> lock(animationMutex_);
66 auto animationItr = animations_.find(animationId);
67 if (animationItr == animations_.end()) {
68 ROSEN_LOGE("Failed to find animation[%{public}" PRIu64 "]!", animationId);
69 return false;
70 }
71 animation = animationItr->second;
72 }
73
74 if (animation == nullptr) {
75 ROSEN_LOGE("Failed to callback animation[%{public}" PRIu64 "], animation is null!", animationId);
76 return false;
77 }
78 if (event == FINISHED) {
79 RemoveAnimationInner(animation);
80 animation->CallFinishCallback();
81 return true;
82 } else if (event == REPEAT_FINISHED) {
83 animation->CallRepeatCallback();
84 return true;
85 } else if (event == LOGICALLY_FINISHED) {
86 animation->CallLogicallyFinishCallback();
87 return true;
88 }
89 ROSEN_LOGE("Failed to callback animation event[%{public}d], event is null!", event);
90 return false;
91 }
92
AddAnimationInner(const std::shared_ptr<RSAnimation> & animation)93 void RSUIContext::AddAnimationInner(const std::shared_ptr<RSAnimation>& animation)
94 {
95 std::unique_lock<std::recursive_mutex> lock(animationMutex_);
96 animations_.emplace(animation->GetId(), animation);
97 animatingPropertyNum_[animation->GetPropertyId()]++;
98 }
99
RemoveAnimationInner(const std::shared_ptr<RSAnimation> & animation)100 void RSUIContext::RemoveAnimationInner(const std::shared_ptr<RSAnimation>& animation)
101 {
102 std::unique_lock<std::recursive_mutex> lock(animationMutex_);
103 if (auto it = animatingPropertyNum_.find(animation->GetPropertyId()); it != animatingPropertyNum_.end()) {
104 it->second--;
105 if (it->second == 0) {
106 animatingPropertyNum_.erase(it);
107 animation->SetPropertyOnAllAnimationFinish();
108 }
109 }
110 animations_.erase(animation->GetId());
111 }
112
SetUITaskRunner(const TaskRunner & uiTaskRunner)113 void RSUIContext::SetUITaskRunner(const TaskRunner& uiTaskRunner)
114 {
115 taskRunner_ = uiTaskRunner;
116 if (rsTransactionHandler_) {
117 rsTransactionHandler_->SetUITaskRunner(uiTaskRunner);
118 }
119 }
120
PostTask(const std::function<void ()> & task)121 void RSUIContext::PostTask(const std::function<void()>& task)
122 {
123 PostDelayTask(task, 0);
124 }
125
PostDelayTask(const std::function<void ()> & task,uint32_t delay)126 void RSUIContext::PostDelayTask(const std::function<void()>& task, uint32_t delay)
127 {
128 if (taskRunner_ == nullptr) {
129 ROSEN_LOGW(
130 "multi-instance RSUIContext::PostDelayTask failed, taskRunner is empty, token=%{public}" PRIu64, token_);
131 auto ctx = RSUIContextManager::Instance().GetRandomUITaskRunnerCtx();
132 if (ctx == nullptr) {
133 ROSEN_LOGE("multi-instance RSUIContext::PostDelayTask, no taskRunner exists");
134 return;
135 }
136 ctx->PostDelayTask(task, delay);
137 return;
138 }
139 taskRunner_(task, delay);
140 ROSEN_LOGD("multi-instance RSUIContext::PostDelayTask success token=%{public}" PRIu64, token_);
141 }
142
DumpNodeTreeProcessor(NodeId nodeId,pid_t pid,uint32_t taskId,std::string & out)143 void RSUIContext::DumpNodeTreeProcessor(NodeId nodeId, pid_t pid, uint32_t taskId, std::string& out)
144 {
145 auto transaction = GetRSTransaction();
146 if (transaction) {
147 out.append("transactionFlags:[ ")
148 .append(std::to_string(pid))
149 .append(", ")
150 .append(std::to_string(transaction->GetTransactionDataIndex()))
151 .append("]\r");
152 }
153 if (auto node = GetNodeMap().GetNode(nodeId)) {
154 constexpr int TOP_LEVEL_DEPTH = 1;
155 node->DumpTree(TOP_LEVEL_DEPTH, out);
156 }
157 if (transaction) {
158 std::unique_ptr<RSCommand> command = std::make_unique<RSCommitDumpClientNodeTree>(nodeId, pid, taskId, out);
159 transaction->AddCommand(command, true);
160 transaction->FlushImplicitTransaction();
161 }
162 }
163 } // namespace Rosen
164 } // namespace OHOS