1 /*
2  * Copyright (c) 2021-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 "pipeline/rs_render_node_map.h"
17 #include "common/rs_common_def.h"
18 #include "pipeline/rs_canvas_drawing_render_node.h"
19 #include "pipeline/rs_render_node.h"
20 #include "pipeline/rs_display_render_node.h"
21 #include "pipeline/rs_render_node_gc.h"
22 #include "pipeline/rs_surface_render_node.h"
23 #include "platform/common/rs_log.h"
24 
25 namespace OHOS {
26 namespace Rosen {
27 namespace {
28 constexpr const char* ENTRY_VIEW = "SCBDesktop";
29 constexpr const char* WALLPAPER_VIEW = "SCBWallpaper";
30 constexpr const char* SCREENLOCK_WINDOW = "SCBScreenLock";
31 constexpr const char* SYSUI_DROPDOWN = "SCBDropdownPanel";
32 constexpr const char* NEGATIVE_SCREEN = "SCBNegativeScreen";
33 };
34 
35 using ResidentSurfaceNodeMap = std::unordered_map<NodeId, std::shared_ptr<RSSurfaceRenderNode>>;
36 
RSRenderNodeMap()37 RSRenderNodeMap::RSRenderNodeMap()
38 {
39     // add animation fallback node, NOTE: this is different from RSContext::globalRootRenderNode_
40     renderNodeMap_[0][0] = std::make_shared<RSBaseRenderNode>(0);
41 }
42 
Initialize(const std::weak_ptr<RSContext> & context)43 void RSRenderNodeMap::Initialize(const std::weak_ptr<RSContext>& context)
44 {
45     context_ = context;
46 }
47 
ObtainLauncherNodeId(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)48 void RSRenderNodeMap::ObtainLauncherNodeId(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)
49 {
50     if (surfaceNode == nullptr) {
51         return;
52     }
53     if (surfaceNode->GetName().find(ENTRY_VIEW) != std::string::npos) {
54         entryViewNodeId_ = surfaceNode->GetId();
55     }
56     if (surfaceNode->GetName().find(WALLPAPER_VIEW) != std::string::npos) {
57         wallpaperViewNodeId_ = surfaceNode->GetId();
58     }
59     if (surfaceNode->GetName().find(NEGATIVE_SCREEN) != std::string::npos) {
60         negativeScreenNodeId_ = surfaceNode->GetId();
61     }
62 }
63 
ObtainScreenLockWindowNodeId(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)64 void RSRenderNodeMap::ObtainScreenLockWindowNodeId(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)
65 {
66     if (surfaceNode == nullptr) {
67         return;
68     }
69     if (surfaceNode->GetName().find(SCREENLOCK_WINDOW) != std::string::npos) {
70         screenLockWindowNodeId_ = surfaceNode->GetId();
71     }
72 }
73 
GetEntryViewNodeId() const74 NodeId RSRenderNodeMap::GetEntryViewNodeId() const
75 {
76     return entryViewNodeId_;
77 }
78 
GetWallPaperViewNodeId() const79 NodeId RSRenderNodeMap::GetWallPaperViewNodeId() const
80 {
81     return wallpaperViewNodeId_;
82 }
83 
GetScreenLockWindowNodeId() const84 NodeId RSRenderNodeMap::GetScreenLockWindowNodeId() const
85 {
86     return screenLockWindowNodeId_;
87 }
88 
GetNegativeScreenNodeId() const89 NodeId RSRenderNodeMap::GetNegativeScreenNodeId() const
90 {
91     return negativeScreenNodeId_;
92 }
93 
IsResidentProcess(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)94 static bool IsResidentProcess(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)
95 {
96     return surfaceNode->GetName().find(ENTRY_VIEW) != std::string::npos ||
97            surfaceNode->GetName().find(SYSUI_DROPDOWN) != std::string::npos ||
98            surfaceNode->GetName().find(SCREENLOCK_WINDOW) != std::string::npos ||
99            surfaceNode->GetName().find(WALLPAPER_VIEW) != std::string::npos;
100 }
101 
GetVisibleLeashWindowCount() const102 uint32_t RSRenderNodeMap::GetVisibleLeashWindowCount() const
103 {
104     if (surfaceNodeMap_.empty()) {
105         return 0;
106     }
107 
108     return std::count_if(surfaceNodeMap_.begin(), surfaceNodeMap_.end(),
109         [](const auto& pair) -> bool {
110             return pair.second && pair.second->IsLeashWindowSurfaceNodeVisible();
111         });
112 }
113 
GetSize() const114 uint64_t RSRenderNodeMap::GetSize() const
115 {
116     size_t mapSize = 0;
117     for (const auto& [_, subMap] : renderNodeMap_) {
118         mapSize += subMap.size();
119     }
120     return static_cast<uint64_t>(mapSize);
121 }
122 
IsResidentProcessNode(NodeId id) const123 bool RSRenderNodeMap::IsResidentProcessNode(NodeId id) const
124 {
125     auto nodePid = ExtractPid(id);
126     return std::any_of(residentSurfaceNodeMap_.begin(), residentSurfaceNodeMap_.end(),
127         [nodePid](const auto& pair) -> bool { return ExtractPid(pair.first) == nodePid; });
128 }
129 
IsUIExtensionSurfaceNode(NodeId id) const130 bool RSRenderNodeMap::IsUIExtensionSurfaceNode(NodeId id) const
131 {
132     std::lock_guard<std::mutex> lock(uiExtensionSurfaceNodesMutex_);
133     return uiExtensionSurfaceNodes_.find(id) != uiExtensionSurfaceNodes_.end();
134 }
135 
AddUIExtensionSurfaceNode(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)136 void RSRenderNodeMap::AddUIExtensionSurfaceNode(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)
137 {
138     if (surfaceNode && surfaceNode->IsUIExtension()) {
139         std::lock_guard<std::mutex> lock(uiExtensionSurfaceNodesMutex_);
140         uiExtensionSurfaceNodes_.insert(surfaceNode->GetId());
141     }
142 }
143 
RemoveUIExtensionSurfaceNode(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)144 void RSRenderNodeMap::RemoveUIExtensionSurfaceNode(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)
145 {
146     if (surfaceNode && surfaceNode->IsUIExtension()) {
147         std::lock_guard<std::mutex> lock(uiExtensionSurfaceNodesMutex_);
148         uiExtensionSurfaceNodes_.erase(surfaceNode->GetId());
149     }
150 }
151 
RegisterRenderNode(const std::shared_ptr<RSBaseRenderNode> & nodePtr)152 bool RSRenderNodeMap::RegisterRenderNode(const std::shared_ptr<RSBaseRenderNode>& nodePtr)
153 {
154     NodeId id = nodePtr->GetId();
155     pid_t pid = ExtractPid(id);
156     if (!(renderNodeMap_[pid].insert({ id, nodePtr })).second) {
157         return false;
158     }
159     nodePtr->OnRegister(context_);
160     if (nodePtr->GetType() == RSRenderNodeType::SURFACE_NODE) {
161         auto surfaceNode = nodePtr->ReinterpretCastTo<RSSurfaceRenderNode>();
162         surfaceNodeMap_.emplace(id, surfaceNode);
163         if (IsResidentProcess(surfaceNode)) {
164             residentSurfaceNodeMap_.emplace(id, surfaceNode);
165         }
166         AddUIExtensionSurfaceNode(surfaceNode);
167         ObtainLauncherNodeId(surfaceNode);
168         ObtainScreenLockWindowNodeId(surfaceNode);
169     } else if (nodePtr->GetType() == RSRenderNodeType::CANVAS_DRAWING_NODE) {
170         auto canvasDrawingNode = nodePtr->ReinterpretCastTo<RSCanvasDrawingRenderNode>();
171         canvasDrawingNodeMap_.emplace(id, canvasDrawingNode);
172     }
173     return true;
174 }
175 
RegisterDisplayRenderNode(const std::shared_ptr<RSDisplayRenderNode> & nodePtr)176 bool RSRenderNodeMap::RegisterDisplayRenderNode(const std::shared_ptr<RSDisplayRenderNode>& nodePtr)
177 {
178     NodeId id = nodePtr->GetId();
179     pid_t pid = ExtractPid(id);
180     if (!(renderNodeMap_[pid].insert({ id, nodePtr })).second) {
181         return false;
182     }
183     displayNodeMap_.emplace(id, nodePtr);
184     nodePtr->OnRegister(context_);
185     return true;
186 }
187 
UnregisterRenderNode(NodeId id)188 void RSRenderNodeMap::UnregisterRenderNode(NodeId id)
189 {
190     pid_t pid = ExtractPid(id);
191     auto it = surfaceNodeMap_.find(id);
192     if (it != surfaceNodeMap_.end()) {
193         if (it->second->GetName().find("ShellAssistantAnco") == std::string::npos) {
194             renderNodeMap_[pid].erase(id);
195         }
196         RemoveUIExtensionSurfaceNode(it->second);
197         surfaceNodeMap_.erase(id);
198     }
199     auto iter = renderNodeMap_.find(pid);
200     if (iter != renderNodeMap_.end()) {
201         iter->second.erase(id);
202         if (iter->second.empty()) {
203             renderNodeMap_.erase(iter);
204         }
205     }
206     residentSurfaceNodeMap_.erase(id);
207     displayNodeMap_.erase(id);
208     canvasDrawingNodeMap_.erase(id);
209     purgeableNodeMap_.erase(id);
210 }
211 
MoveRenderNodeMap(std::shared_ptr<std::unordered_map<NodeId,std::shared_ptr<RSBaseRenderNode>>> subRenderNodeMap,pid_t pid)212 void RSRenderNodeMap::MoveRenderNodeMap(
213     std::shared_ptr<std::unordered_map<NodeId, std::shared_ptr<RSBaseRenderNode>>> subRenderNodeMap, pid_t pid)
214 {
215     if (!subRenderNodeMap) {
216         return;
217     }
218     auto iter = renderNodeMap_.find(pid);
219     if (iter != renderNodeMap_.end()) {
220         auto& subMap = iter->second;
221         // remove node from tree
222         for (auto subIter = subMap.begin(); subIter != subMap.end();) {
223             subIter->second->RemoveFromTree(false);
224             subRenderNodeMap->emplace(subIter->first, subIter->second);
225             subIter = subMap.erase(subIter);
226         }
227         renderNodeMap_.erase(iter);
228     }
229 }
230 
FilterNodeByPid(pid_t pid)231 void RSRenderNodeMap::FilterNodeByPid(pid_t pid)
232 {
233     ROSEN_LOGD("RSRenderNodeMap::FilterNodeByPid removing all nodes belong to pid %{public}llu",
234         (unsigned long long)pid);
235     bool useBatchRemoving =
236         RSUniRenderJudgement::IsUniRender() && RSSystemProperties::GetBatchRemovingOnRemoteDiedEnabled();
237     // remove all nodes belong to given pid (by matching higher 32 bits of node id)
238     auto iter = renderNodeMap_.find(pid);
239     if (iter != renderNodeMap_.end()) {
240         auto& subMap = iter->second;
241         for (auto subIter = subMap.begin(); subIter != subMap.end();) {
242             if (subIter->second == nullptr) {
243                 subIter = subMap.erase(subIter);
244                 continue;
245             }
246             if (useBatchRemoving) {
247                 RSRenderNodeGC::Instance().AddToOffTreeNodeBucket(subIter->second);
248             } else if (auto parent = subIter->second->GetParent().lock()) {
249                 parent->RemoveChildFromFulllist(subIter->second->GetId());
250                 subIter->second->RemoveFromTree(false);
251             } else {
252                 subIter->second->RemoveFromTree(false);
253             }
254             subIter->second->GetAnimationManager().FilterAnimationByPid(pid);
255             subIter = subMap.erase(subIter);
256         }
257         renderNodeMap_.erase(iter);
258     }
259     EraseIf(surfaceNodeMap_, [pid, useBatchRemoving, this](const auto& pair) -> bool {
260         bool shouldErase = (ExtractPid(pair.first) == pid);
261         if (shouldErase) {
262             RemoveUIExtensionSurfaceNode(pair.second);
263         }
264         if (shouldErase && pair.second && useBatchRemoving) {
265             if (auto parent = pair.second->GetParent().lock()) {
266                 parent->RemoveChildFromFulllist(pair.second->GetId());
267             }
268             pair.second->RemoveFromTree(false);
269         }
270         return shouldErase;
271     });
272 
273     EraseIf(residentSurfaceNodeMap_, [pid](const auto& pair) -> bool {
274         return ExtractPid(pair.first) == pid;
275     });
276 
277     EraseIf(canvasDrawingNodeMap_, [pid](const auto& pair) -> bool {
278         return ExtractPid(pair.first) == pid;
279     });
280 
281     EraseIf(displayNodeMap_, [pid](const auto& pair) -> bool {
282         if (ExtractPid(pair.first) != pid && pair.second) {
283             ROSEN_LOGD("RSRenderNodeMap::FilterNodeByPid removing all nodes belong to pid %{public}llu",
284                 (unsigned long long)pid);
285             pair.second->FilterModifiersByPid(pid);
286         }
287         return ExtractPid(pair.first) == pid;
288     });
289 
290     if (auto fallbackNode = GetAnimationFallbackNode()) {
291         // remove all fallback animations belong to given pid
292         fallbackNode->GetAnimationManager().FilterAnimationByPid(pid);
293     }
294 }
295 
TraversalNodes(std::function<void (const std::shared_ptr<RSBaseRenderNode> &)> func) const296 void RSRenderNodeMap::TraversalNodes(std::function<void (const std::shared_ptr<RSBaseRenderNode>&)> func) const
297 {
298     for (const auto& [_, subMap] : renderNodeMap_) {
299         for (const auto& [_, node] : subMap) {
300             func(node);
301         }
302     }
303 }
304 
TraverseCanvasDrawingNodes(std::function<void (const std::shared_ptr<RSCanvasDrawingRenderNode> &)> func) const305 void RSRenderNodeMap::TraverseCanvasDrawingNodes(
306     std::function<void(const std::shared_ptr<RSCanvasDrawingRenderNode>&)> func) const
307 {
308     for (const auto& [_, node] : canvasDrawingNodeMap_) {
309         func(node);
310     }
311 }
312 
TraverseSurfaceNodes(std::function<void (const std::shared_ptr<RSSurfaceRenderNode> &)> func) const313 void RSRenderNodeMap::TraverseSurfaceNodes(std::function<void (const std::shared_ptr<RSSurfaceRenderNode>&)> func) const
314 {
315     for (const auto& [_, node] : surfaceNodeMap_) {
316         func(node);
317     }
318 }
319 
ContainPid(pid_t pid) const320 bool RSRenderNodeMap::ContainPid(pid_t pid) const
321 {
322     return std::any_of(surfaceNodeMap_.begin(), surfaceNodeMap_.end(),
323         [pid](const auto& pair) -> bool { return ExtractPid(pair.first) == pid; });
324 }
325 
TraverseDisplayNodes(std::function<void (const std::shared_ptr<RSDisplayRenderNode> &)> func) const326 void RSRenderNodeMap::TraverseDisplayNodes(std::function<void (const std::shared_ptr<RSDisplayRenderNode>&)> func) const
327 {
328     for (const auto& [_, node] : displayNodeMap_) {
329         func(node);
330     }
331 }
332 
GetResidentSurfaceNodeMap() const333 const ResidentSurfaceNodeMap& RSRenderNodeMap::GetResidentSurfaceNodeMap() const
334 {
335     return residentSurfaceNodeMap_;
336 }
337 
338 template<>
GetRenderNode(NodeId id) const339 const std::shared_ptr<RSBaseRenderNode> RSRenderNodeMap::GetRenderNode(NodeId id) const
340 {
341     pid_t pid = ExtractPid(id);
342     auto iter = renderNodeMap_.find(pid);
343     if (iter != renderNodeMap_.end()) {
344         auto subIter = (iter->second).find(id);
345         if (subIter != (iter->second).end()) {
346             return subIter->second;
347         }
348     }
349     return nullptr;
350 }
351 
GetAnimationFallbackNode() const352 const std::shared_ptr<RSRenderNode> RSRenderNodeMap::GetAnimationFallbackNode() const
353 {
354     auto iter = renderNodeMap_.find(0);
355     if (iter != renderNodeMap_.cend()) {
356         if (auto subIter = iter->second.find(0); subIter != iter->second.end()) {
357             return subIter->second;
358         }
359     }
360     return nullptr;
361 }
362 
AddOffTreeNode(NodeId nodeId)363 void RSRenderNodeMap::AddOffTreeNode(NodeId nodeId)
364 {
365     purgeableNodeMap_.insert(std::pair(nodeId, true));
366 }
367 
RemoveOffTreeNode(NodeId nodeId)368 void RSRenderNodeMap::RemoveOffTreeNode(NodeId nodeId)
369 {
370     purgeableNodeMap_.insert(std::pair(nodeId, false));
371 }
372 
GetAndClearPurgeableNodeIds()373 std::unordered_map<NodeId, bool>&& RSRenderNodeMap::GetAndClearPurgeableNodeIds()
374 {
375     return std::move(purgeableNodeMap_);
376 }
377 
GetSelfDrawSurfaceNameByPid(pid_t nodePid) const378 const std::string RSRenderNodeMap::GetSelfDrawSurfaceNameByPid(pid_t nodePid) const
379 {
380     for (auto &t : surfaceNodeMap_) {
381         if (ExtractPid(t.first) == nodePid && t.second->IsSelfDrawingType()) {
382             return t.second->GetName();
383         }
384     }
385     ROSEN_LOGD("RSRenderNodeMap::GetSurfaceNameByPid no self drawing nodes belong to pid %{public}d",
386         static_cast<int32_t>(nodePid));
387     return "";
388 }
389 
390 } // namespace Rosen
391 } // namespace OHOS
392