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