1 /*
2 * Copyright (c) 2022 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 #include "window_extension_connection_ohos_ng.h"
16
17 #include "render_service_client/core/ui/rs_surface_node.h"
18
19 #include "base/memory/ace_type.h"
20 #include "base/memory/referenced.h"
21 #include "core/common/ace_engine.h"
22 #include "core/common/container.h"
23 #include "core/common/container_scope.h"
24 #include "core/components_ng/pattern/ability_component/ability_component_pattern.h"
25 #include "core/components_ng/render/adapter/rosen_render_context.h"
26 #include "frameworks/base/json/json_util.h"
27 #include "core/pipeline_ng/pipeline_context.h"
28
29 #ifdef OS_ACCOUNT_EXISTS
30 #include "os_account_manager.h"
31 #endif
32
33 namespace OHOS::Ace {
34 class NGConnectionCallback : public Rosen::IWindowExtensionCallback {
35 public:
36 ACE_DISALLOW_COPY_AND_MOVE(NGConnectionCallback);
NGConnectionCallback(const WeakPtr<NG::FrameNode> & originNode,int32_t instanceId)37 NGConnectionCallback(const WeakPtr<NG::FrameNode>& originNode, int32_t instanceId)
38 : originNode_(originNode), instanceId_(instanceId)
39 {}
40
41 ~NGConnectionCallback() override = default;
OnWindowReady(const std::shared_ptr<Rosen::RSSurfaceNode> & rsSurfaceNode)42 void OnWindowReady(const std::shared_ptr<Rosen::RSSurfaceNode>& rsSurfaceNode) override
43 {
44 LOGI("OnWindowReady called");
45 auto task = [weak = wptr<NGConnectionCallback>(this), weakOriginNode = originNode_, rsNode = rsSurfaceNode,
46 instanceId = instanceId_]() {
47 ContainerScope scope(instanceId);
48 CHECK_NULL_VOID(rsNode);
49 auto nodeStrong = weakOriginNode.Upgrade();
50 CHECK_NULL_VOID(nodeStrong);
51 auto context = nodeStrong->GetRenderContext();
52 CHECK_NULL_VOID(context);
53 auto extensionCallback = weak.promote();
54 CHECK_NULL_VOID(extensionCallback);
55 extensionCallback->rsOriginNode_ = std::static_pointer_cast<Rosen::RSSurfaceNode>(
56 AceType::DynamicCast<NG::RosenRenderContext>(context)->GetRSNode());
57 UpdateFrameNodeTree(nodeStrong, rsNode);
58 auto pattern = AceType::DynamicCast<NG::AbilityComponentPattern>(nodeStrong->GetPattern());
59 if (pattern) {
60 pattern->FireConnect();
61 }
62 };
63 PostTaskToUI(std::move(task), "ArkUIWindowExtensionConnect");
64 }
65
OnExtensionDisconnected()66 void OnExtensionDisconnected() override
67 {
68 LOGI("window extension disconnect");
69 auto task = [weak = originNode_, rsNode = rsOriginNode_, instanceId = instanceId_]() {
70 ContainerScope scope(instanceId);
71 auto node = weak.Upgrade();
72 CHECK_NULL_VOID(node);
73 UpdateFrameNodeTree(node, rsNode);
74 auto pattern = AceType::DynamicCast<NG::AbilityComponentPattern>(node->GetPattern());
75 if (pattern) {
76 pattern->FireDisConnect();
77 }
78 };
79 PostTaskToUI(std::move(task), "ArkUIWindowExtensionDisconnect");
80 }
81
OnKeyEvent(const std::shared_ptr<MMI::KeyEvent> & event)82 void OnKeyEvent(const std::shared_ptr<MMI::KeyEvent>& event) override {}
OnPointerEvent(const std::shared_ptr<MMI::PointerEvent> & event)83 void OnPointerEvent(const std::shared_ptr<MMI::PointerEvent>& event) override {}
OnBackPress()84 void OnBackPress() override {}
85
86 private:
PostTaskToUI(const std::function<void ()> && task,const std::string & name) const87 void PostTaskToUI(const std::function<void()>&& task, const std::string& name) const
88 {
89 CHECK_NULL_VOID(task);
90 auto container = AceEngine::Get().GetContainer(instanceId_);
91 CHECK_NULL_VOID(container);
92 auto context = container->GetPipelineContext();
93 CHECK_NULL_VOID(context);
94 auto taskExecutor = context->GetTaskExecutor();
95 CHECK_NULL_VOID(taskExecutor);
96 taskExecutor->PostTask(task, TaskExecutor::TaskType::UI, name);
97 }
98
UpdateFrameNodeTree(const RefPtr<NG::FrameNode> & node,const std::shared_ptr<Rosen::RSSurfaceNode> & rsSurfaceNode)99 static void UpdateFrameNodeTree(
100 const RefPtr<NG::FrameNode>& node, const std::shared_ptr<Rosen::RSSurfaceNode>& rsSurfaceNode)
101 {
102 CHECK_NULL_VOID(rsSurfaceNode);
103 rsSurfaceNode->CreateNodeInRenderThread();
104 auto context = node->GetRenderContext();
105 CHECK_NULL_VOID(context);
106 auto geometryNode = node->GetGeometryNode();
107 auto size = geometryNode->GetFrameSize();
108 geometryNode->SetFrameOffset(context->GetPaintRectWithTransform().GetOffset());
109 node->SetGeometryNode(geometryNode);
110 auto offset = node->GetGeometryNode()->GetFrameOffset();
111 LOGI("OnWindowReady surface size:%{public}f %{public}f %{public}f %{public}f", offset.GetX(), offset.GetY(),
112 size.Width(), size.Height());
113 rsSurfaceNode->SetBounds(offset.GetX(), offset.GetY(), size.Width(), size.Height());
114 AceType::DynamicCast<NG::RosenRenderContext>(context)->SetRSNode(rsSurfaceNode);
115 auto parent = node->GetParent();
116 CHECK_NULL_VOID(parent);
117 parent->MarkNeedSyncRenderTree();
118 parent->RebuildRenderContextTree();
119 context->RequestNextFrame();
120 }
121
122 WeakPtr<NG::FrameNode> originNode_;
123 std::shared_ptr<Rosen::RSSurfaceNode> rsOriginNode_;
124 int32_t instanceId_ = -1;
125 };
126
RectConverterNG(const Rect & rect,Rosen::Rect & rosenRect)127 void RectConverterNG(const Rect& rect, Rosen::Rect& rosenRect)
128 {
129 rosenRect.posX_ = static_cast<int>(rect.GetOffset().GetX());
130 rosenRect.posY_ = static_cast<int>(rect.GetOffset().GetY());
131 rosenRect.width_ = static_cast<uint32_t>(rect.GetSize().Width());
132 rosenRect.height_ = static_cast<uint32_t>(rect.GetSize().Height());
133 }
134
WantConverterNG(const std::string & want,AppExecFwk::ElementName & element)135 void WantConverterNG(const std::string& want, AppExecFwk::ElementName& element)
136 {
137 auto json = JsonUtil::ParseJsonString(want);
138 element.SetAbilityName(json->GetValue("abilityName")->GetString());
139 element.SetBundleName(json->GetValue("bundleName")->GetString());
140 }
141
ConnectExtension(const RefPtr<NG::FrameNode> & node,int32_t windowId)142 void WindowExtensionConnectionAdapterOhosNG::ConnectExtension(const RefPtr<NG::FrameNode>& node, int32_t windowId)
143 {
144 #if defined(ENABLE_ROSEN_BACKEND) && defined(OS_ACCOUNT_EXISTS)
145 LOGI("connect to windows extension begin");
146 if (!windowExtension_) {
147 windowExtension_ = std::make_unique<Rosen::WindowExtensionConnection>();
148 }
149 std::vector<int32_t> userIds;
150 ErrCode code = AccountSA::OsAccountManager::QueryActiveOsAccountIds(userIds);
151 if (code != ERR_OK) {
152 LOGE("fail to queryAccountId, so cannot connect extension");
153 return;
154 }
155 auto size = node->GetGeometryNode()->GetFrameSize();
156 auto offset = node->GetGeometryNode()->GetFrameOffset() + node->GetGeometryNode()->GetParentGlobalOffset();
157
158 Rosen::Rect rosenRect = {
159 static_cast<int32_t>(offset.GetX()),
160 static_cast<int32_t>(offset.GetY()),
161 static_cast<uint32_t>(size.Width()),
162 static_cast<uint32_t>(size.Height()),
163 };
164 auto renderProperty = node->GetPaintProperty<NG::AbilityComponentRenderProperty>();
165 if (!renderProperty->HasWant()) {
166 LOGE("fail to get want value");
167 return;
168 }
169 std::string want = renderProperty->GetWantValue();
170 AppExecFwk::ElementName element;
171 WantConverterNG(want, element);
172
173 int32_t instanceId = -1;
174 auto container = Container::Current();
175 if (container) {
176 instanceId = container->GetInstanceId();
177 }
178 sptr<Rosen::IWindowExtensionCallback> callback = new NGConnectionCallback(node, instanceId);
179 if (extensionSession_ != nullptr) {
180 windowExtension_->ConnectExtension(element, rosenRect, userIds.front(), windowId, callback, extensionSession_);
181 } else {
182 windowExtension_->ConnectExtension(element, rosenRect, userIds.front(), windowId, callback);
183 }
184 #endif
185 }
186
RemoveExtension()187 void WindowExtensionConnectionAdapterOhosNG::RemoveExtension()
188 {
189 if (windowExtension_) {
190 LOGI("remove extension");
191 windowExtension_->DisconnectExtension();
192 }
193 }
194
Show()195 void WindowExtensionConnectionAdapterOhosNG::Show()
196 {
197 LOGI("show WindowExtensionConnectionAdapterOhos");
198 if (windowExtension_) {
199 windowExtension_->Show();
200 }
201 }
202
Hide()203 void WindowExtensionConnectionAdapterOhosNG::Hide()
204 {
205 LOGI("hide WindowExtensionConnectionAdapterOhos");
206 if (windowExtension_) {
207 windowExtension_->Hide();
208 }
209 }
210
UpdateRect(const Rect & rect)211 void WindowExtensionConnectionAdapterOhosNG::UpdateRect(const Rect& rect)
212 {
213 if (windowExtension_) {
214 Rosen::Rect rosenRect;
215 RectConverterNG(rect, rosenRect);
216 LOGI("UpdateRect rect: %{public}s", rect.ToString().c_str());
217 windowExtension_->SetBounds(rosenRect);
218 }
219 }
220 } // namespace OHOS::Ace
221