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