• 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 "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