• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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