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 "core/components_ng/render/adapter/component_snapshot.h"
17
18 #include <memory>
19
20 #include "transaction/rs_interfaces.h"
21
22 #include "bridge/common/utils/utils.h"
23 #include "core/components_ng/base/frame_node.h"
24 #include "core/components_ng/base/inspector.h"
25 #include "core/components_ng/render/adapter/rosen_render_context.h"
26 #include "core/pipeline_ng/pipeline_context.h"
27
28 namespace OHOS::Ace::NG {
29 namespace {
30 class CustomizedCallback : public Rosen::SurfaceCaptureCallback {
31 public:
CustomizedCallback(ComponentSnapshot::JsCallback && jsCallback)32 explicit CustomizedCallback(ComponentSnapshot::JsCallback&& jsCallback) : callback_(std::move(jsCallback)) {}
33 ~CustomizedCallback() override = default;
OnSurfaceCapture(std::shared_ptr<Media::PixelMap> pixelMap)34 void OnSurfaceCapture(std::shared_ptr<Media::PixelMap> pixelMap) override
35 {
36 CHECK_NULL_VOID(callback_);
37 if (!pixelMap) {
38 LOGW("snapshot creation failed");
39 callback_(nullptr, Framework::ERROR_CODE_INTERNAL_ERROR);
40 } else {
41 LOGI("snapshot created successfully");
42 callback_(pixelMap, Framework::ERROR_CODE_NO_ERROR);
43 }
44 }
45
46 private:
47 ComponentSnapshot::JsCallback callback_;
48 };
49 } // namespace
50
GetRsNode(const RefPtr<FrameNode> & node)51 std::shared_ptr<Rosen::RSNode> ComponentSnapshot::GetRsNode(const RefPtr<FrameNode>& node)
52 {
53 CHECK_NULL_RETURN(node, nullptr);
54 auto context = AceType::DynamicCast<RosenRenderContext>(node->GetRenderContext());
55 CHECK_NULL_RETURN(context, nullptr);
56 auto rsNode = context->GetRSNode();
57 return rsNode;
58 }
59
Get(const std::string & componentId,JsCallback && callback)60 void ComponentSnapshot::Get(const std::string& componentId, JsCallback&& callback)
61 {
62 auto node = Inspector::GetFrameNodeByKey(componentId);
63 if (!node) {
64 LOGW("node not found %{public}s", componentId.c_str());
65 callback(nullptr, Framework::ERROR_CODE_INTERNAL_ERROR);
66 return;
67 }
68 auto rsNode = GetRsNode(node);
69 auto& rsInterface = Rosen::RSInterfaces::GetInstance();
70 LOGI("TakeSurfaceCaptureForUI");
71 rsInterface.TakeSurfaceCaptureForUI(rsNode, std::make_shared<CustomizedCallback>(std::move(callback)));
72 }
73
Create(const RefPtr<AceType> & customNode,JsCallback && callback,const int32_t delayTime)74 void ComponentSnapshot::Create(const RefPtr<AceType>& customNode, JsCallback&& callback, const int32_t delayTime)
75 {
76 auto node = AceType::DynamicCast<FrameNode>(customNode);
77 if (!node) {
78 LOGW("builder is invalid");
79 callback(nullptr, Framework::ERROR_CODE_INTERNAL_ERROR);
80 return;
81 }
82
83 FrameNode::ProcessOffscreenNode(node);
84 LOGD("ProcessOffscreenNode finished, root size = %{public}s",
85 node->GetGeometryNode()->GetFrameSize().ToString().c_str());
86
87 auto pipeline = PipelineContext::GetCurrentContext();
88 CHECK_NULL_VOID(pipeline);
89 auto executor = pipeline->GetTaskExecutor();
90 CHECK_NULL_VOID(executor);
91
92 executor->PostDelayedTask(
93 [callback, node]() mutable {
94 auto rsNode = GetRsNode(node);
95 LOGI("TakeSurfaceCaptureForUI rootNode = %{public}s", node->GetTag().c_str());
96 auto& rsInterface = Rosen::RSInterfaces::GetInstance();
97 rsInterface.TakeSurfaceCaptureForUI(rsNode, std::make_shared<CustomizedCallback>(std::move(callback)));
98 },
99 TaskExecutor::TaskType::UI, delayTime);
100 }
101 } // namespace OHOS::Ace::NG
102