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