• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/pattern/window_scene/scene/system_window_scene.h"
17 
18 #include "ui/rs_canvas_node.h"
19 #include "ui/rs_surface_node.h"
20 
21 #include "adapter/ohos/entrance/mmi_event_convertor.h"
22 #include "core/components_ng/pattern/window_scene/helper/window_scene_helper.h"
23 #include "core/components_ng/pattern/window_scene/scene/window_event_process.h"
24 #include "core/components_ng/render/adapter/rosen_render_context.h"
25 #include "core/pipeline_ng/pipeline_context.h"
26 
27 namespace OHOS::Ace::NG {
28 namespace {
29 constexpr uint32_t DELAY_TIME = 3000;
30 } // namespace
31 
SystemWindowScene(const sptr<Rosen::Session> & session)32 SystemWindowScene::SystemWindowScene(const sptr<Rosen::Session>& session) : session_(session)
33 {
34     boundsChangedCallback_ = [weakThis = WeakClaim(this)](const Rosen::Vector4f& bounds) {
35         auto self = weakThis.Upgrade();
36         CHECK_NULL_VOID(self);
37         self->OnBoundsChanged(bounds);
38     };
39 }
40 
GetSession()41 sptr<Rosen::Session> SystemWindowScene::GetSession()
42 {
43     return session_;
44 }
45 
OnBoundsChanged(const Rosen::Vector4f & bounds)46 void SystemWindowScene::OnBoundsChanged(const Rosen::Vector4f& bounds)
47 {
48     Rosen::WSRect windowRect {
49         .posX_ = std::round(bounds.x_),
50         .posY_ = std::round(bounds.y_),
51         .width_ = std::round(bounds.z_),
52         .height_ = std::round(bounds.w_),
53     };
54 
55     CHECK_NULL_VOID(session_);
56     Rosen::WSRectF originBounds = {
57         .posX_ = bounds.x_,
58         .posY_ = bounds.y_,
59         .width_ = bounds.z_,
60         .height_ = bounds.w_,
61     };
62     session_->SetBounds(originBounds);
63     windowRect.posX_ = std::round(bounds.x_ + session_->GetOffsetX());
64     windowRect.posY_ = std::round(bounds.y_ + session_->GetOffsetY());
65     session_->UpdateRect(windowRect, Rosen::SizeChangeReason::UNDEFINED, "OnBoundsChanged");
66 }
67 
OnVisibleChange(bool visible)68 void SystemWindowScene::OnVisibleChange(bool visible)
69 {
70     CHECK_NULL_VOID(session_);
71     TAG_LOGI(AceLogTag::ACE_WINDOW_SCENE, "Visibility of %{public}s[id:%{public}d] changed: %{public}s",
72         session_->GetSessionInfo().bundleName_.c_str(), session_->GetPersistentId(), visible ? "visible" : "invisible");
73     if (visible && session_->NeedCheckContextTransparent()) {
74         PostCheckContextTransparentTask();
75     } else if (session_->NeedCheckContextTransparent()) {
76         checkContextTransparentTask_.Cancel();
77     }
78     if (SystemProperties::GetFaultInjectEnabled() && session_->NeedCheckContextTransparent()) {
79         PostFaultInjectTask();
80     }
81 }
82 
OnAttachToFrameNode()83 void SystemWindowScene::OnAttachToFrameNode()
84 {
85     CHECK_NULL_VOID(session_);
86     auto host = GetHost();
87     CHECK_NULL_VOID(host);
88     ACE_SCOPED_TRACE("OnAttachToFrameNode[id:%d][self:%d][type:%d][name:%s]",
89         session_->GetPersistentId(), host->GetId(), session_->GetWindowType(), session_->GetWindowName().c_str());
90     TAG_LOGI(AceLogTag::ACE_WINDOW_SCENE,
91         "OnAttachToFrameNode id: %{public}d, node id: %{public}d, type: %{public}d, name: %{public}s",
92         session_->GetPersistentId(), host->GetId(), session_->GetWindowType(), session_->GetWindowName().c_str());
93 
94     host->SetWindowBoundary();
95     session_->SetUINodeId(host->GetAccessibilityId());
96     auto surfaceNode = session_->GetSurfaceNode();
97     CHECK_NULL_VOID(surfaceNode);
98     auto context = AceType::DynamicCast<NG::RosenRenderContext>(host->GetRenderContext());
99     CHECK_NULL_VOID(context);
100     context->SetRSNode(surfaceNode);
101     surfaceNode->SetBoundsChangedCallback(boundsChangedCallback_);
102 
103     auto mouseEventHub = host->GetOrCreateInputEventHub();
104     auto mouseCallback = [weakThis = WeakClaim(this), weakSession = wptr(session_)](MouseInfo& info) {
105         auto self = weakThis.Upgrade();
106         CHECK_NULL_VOID(self);
107         auto session = weakSession.promote();
108         CHECK_NULL_VOID(session);
109         const auto pointerEvent = info.GetPointerEvent();
110         CHECK_NULL_VOID(pointerEvent);
111         auto host = self->GetHost();
112         if (host != nullptr) {
113             DelayedSingleton<WindowEventProcess>::GetInstance()->ProcessWindowMouseEvent(
114                 host->GetId(), session, pointerEvent);
115             DelayedSingleton<WindowEventProcess>::GetInstance()->ProcessWindowDragEvent(
116                 host->GetId(), session, pointerEvent);
117         }
118         session->TransferPointerEvent(pointerEvent);
119     };
120     mouseEventHub->SetMouseEvent(std::move(mouseCallback));
121 
122     RegisterFocusCallback();
123     RegisterEventCallback();
124     RegisterResponseRegionCallback();
125 
126     if (session_->NeedCheckContextTransparent()) {
127         PostCheckContextTransparentTask();
128     }
129 }
130 
OnDetachFromFrameNode(FrameNode * frameNode)131 void SystemWindowScene::OnDetachFromFrameNode(FrameNode* frameNode)
132 {
133     CHECK_NULL_VOID(session_);
134     CHECK_NULL_VOID(frameNode);
135     ACE_SCOPED_TRACE("OnDetachFromFrameNode[id:%d][self:%d][type:%d][name:%s]",
136         session_->GetPersistentId(), frameNode->GetId(), session_->GetWindowType(), session_->GetWindowName().c_str());
137     TAG_LOGI(AceLogTag::ACE_WINDOW_SCENE,
138         "OnDetachFromFrameNode id: %{public}d, node id: %{public}d, type: %{public}d, name: %{public}s",
139         session_->GetPersistentId(), frameNode->GetId(), session_->GetWindowType(), session_->GetWindowName().c_str());
140     if (session_->NeedCheckContextTransparent()) {
141         checkContextTransparentTask_.Cancel();
142     }
143 }
144 
OnAttachToMainTree()145 void SystemWindowScene::OnAttachToMainTree()
146 {
147     auto host = GetHost();
148     CHECK_NULL_VOID(host);
149     auto context = host->GetRenderContext();
150     CHECK_NULL_VOID(context);
151     context->SetIsNeedRebuildRSTree(true);
152 }
153 
OnDetachFromMainTree()154 void SystemWindowScene::OnDetachFromMainTree()
155 {
156     auto host = GetHost();
157     CHECK_NULL_VOID(host);
158     auto context = host->GetRenderContext();
159     CHECK_NULL_VOID(context);
160     context->SetIsNeedRebuildRSTree(false);
161 }
162 
RegisterEventCallback()163 void SystemWindowScene::RegisterEventCallback()
164 {
165     CHECK_NULL_VOID(session_);
166     auto pointerEventCallback =
167         [weakThis = WeakClaim(this), instanceId = instanceId_](std::shared_ptr<MMI::PointerEvent> PointerEvent) {
168             ContainerScope Scope(instanceId);
169             auto pipelineContext = PipelineContext::GetCurrentContext();
170             if (!pipelineContext) {
171                 TAG_LOGE(AceLogTag::ACE_INPUTTRACKING,
172                     "PipelineContext GetCurrentContext null,id:%{public}d", PointerEvent->GetId());
173                 PointerEvent->MarkProcessed();
174                 return;
175             }
176             auto taskExecutor = pipelineContext->GetTaskExecutor();
177             if (!taskExecutor) {
178                 TAG_LOGE(AceLogTag::ACE_INPUTTRACKING, "taskExecutor is null,id:%{public}d", PointerEvent->GetId());
179                 PointerEvent->MarkProcessed();
180                 return;
181             }
182             taskExecutor->PostTask([weakThis, PointerEvent]() {
183                 auto self = weakThis.Upgrade();
184                 if (!self) {
185                     TAG_LOGE(AceLogTag::ACE_INPUTTRACKING,
186                         "weakThis Upgrade null,id:%{public}d", PointerEvent->GetId());
187                     PointerEvent->MarkProcessed();
188                     return;
189                 }
190                 auto host = self->GetHost();
191                 if (!host) {
192                     TAG_LOGE(AceLogTag::ACE_INPUTTRACKING,
193                         "GetHost null,id:%{public}d", PointerEvent->GetId());
194                     PointerEvent->MarkProcessed();
195                     return;
196                 }
197                 WindowSceneHelper::InjectPointerEvent(host, PointerEvent);
198             },
199                 TaskExecutor::TaskType::UI, "ArkUIWindowInjectPointerEvent", PriorityType::VIP);
200     };
201     session_->SetNotifySystemSessionPointerEventFunc(std::move(pointerEventCallback));
202 
203     auto keyEventCallback = [instanceId = instanceId_](std::shared_ptr<MMI::KeyEvent> KeyEvent,
204         bool isPreImeEvent) -> bool {
205         ContainerScope Scope(instanceId);
206         return WindowSceneHelper::InjectKeyEvent(KeyEvent, isPreImeEvent);
207     };
208     session_->SetNotifySystemSessionKeyEventFunc(std::move(keyEventCallback));
209 }
210 
RegisterResponseRegionCallback()211 void SystemWindowScene::RegisterResponseRegionCallback()
212 {
213     auto host = GetHost();
214     CHECK_NULL_VOID(host);
215     auto gestureHub = host->GetOrCreateGestureEventHub();
216     CHECK_NULL_VOID(gestureHub);
217 
218     auto touchCallback = [weakSession = wptr(session_)](TouchEventInfo& info) {
219         auto session = weakSession.promote();
220         CHECK_NULL_VOID(session);
221         const auto pointerEvent = info.GetPointerEvent();
222         CHECK_NULL_VOID(pointerEvent);
223         session->TransferPointerEvent(pointerEvent);
224     };
225     gestureHub->SetTouchEvent(std::move(touchCallback));
226 
227     auto responseRegionCallback = [weakThis = WeakClaim(this), weakSession = wptr(session_)](
228         const std::vector<DimensionRect>& responseRegion) {
229         auto self = weakThis.Upgrade();
230         CHECK_NULL_VOID(self);
231         auto session = weakSession.promote();
232         CHECK_NULL_VOID(session);
233         std::vector<Rosen::Rect> hotAreas;
234         for (auto& rect : responseRegion) {
235             Rosen::Rect windowRect {
236                 .posX_ = std::round(rect.GetOffset().GetX().Value()),
237                 .posY_ = std::round(rect.GetOffset().GetY().Value()),
238                 .width_ = std::round(rect.GetWidth().Value()),
239                 .height_ = std::round(rect.GetHeight().Value()),
240             };
241             hotAreas.push_back(windowRect);
242         }
243         session->SetTouchHotAreas(hotAreas);
244     };
245     gestureHub->SetResponseRegionFunc(responseRegionCallback);
246 }
247 
GetWindowPatternType() const248 uint32_t SystemWindowScene::GetWindowPatternType() const
249 {
250     return static_cast<uint32_t>(WindowPatternType::SYSTEM_WINDOW_SCENE);
251 }
252 
RegisterFocusCallback()253 void SystemWindowScene::RegisterFocusCallback()
254 {
255     CHECK_NULL_VOID(session_);
256 
257     auto requestFocusCallback = [weakThis = WeakClaim(this), frameNode = frameNode_, instanceId = instanceId_]() {
258         ContainerScope scope(instanceId);
259         auto pipelineContext = PipelineContext::GetCurrentContext();
260         CHECK_NULL_VOID(pipelineContext);
261         pipelineContext->SetFocusedWindowSceneNode(frameNode);
262         pipelineContext->PostAsyncEvent([weakThis]() {
263             auto pipeline = PipelineContext::GetCurrentContext();
264             CHECK_NULL_VOID(pipeline);
265             pipeline->SetIsFocusActive(false);
266             auto self = weakThis.Upgrade();
267             CHECK_NULL_VOID(self);
268             self->FocusViewShow();
269         }, "ArkUIWindowFocusViewShow", TaskExecutor::TaskType::UI);
270     };
271     session_->SetNotifyUIRequestFocusFunc(requestFocusCallback);
272 
273     auto lostFocusCallback = [weakThis = WeakClaim(this), instanceId = instanceId_]() {
274         ContainerScope scope(instanceId);
275         auto pipelineContext = PipelineContext::GetCurrentContext();
276         CHECK_NULL_VOID(pipelineContext);
277         pipelineContext->PostAsyncEvent([weakThis]() {
278             auto pipeline = PipelineContext::GetCurrentContext();
279             CHECK_NULL_VOID(pipeline);
280             auto self = weakThis.Upgrade();
281             CHECK_NULL_VOID(self);
282             CHECK_NULL_VOID(self->GetSession());
283             pipeline->RestoreDefault(self->GetSession()->GetPersistentId());
284         }, "ArkUIWindowLostFocus", TaskExecutor::TaskType::UI);
285     };
286     session_->SetNotifyUILostFocusFunc(lostFocusCallback);
287 }
288 
LostViewFocus()289 void SystemWindowScene::LostViewFocus()
290 {
291     TAG_LOGI(
292         AceLogTag::ACE_FOCUS, "Focus view: %{public}s/%{public}d lost focus", GetFrameName().c_str(), GetFrameId());
293     auto focusHub = GetFocusHub();
294     if (!focusHub || !focusHub->IsCurrentFocus()) {
295         return;
296     }
297     auto pipeline = PipelineContext::GetCurrentContext();
298     CHECK_NULL_VOID(pipeline);
299     auto screenNode = pipeline->GetScreenNode();
300     CHECK_NULL_VOID(screenNode);
301     auto screenNodeFocusHub = screenNode->GetFocusHub();
302     CHECK_NULL_VOID(screenNodeFocusHub);
303     screenNodeFocusHub->LostFocus(BlurReason::VIEW_SWITCH);
304 }
305 
PostCheckContextTransparentTask()306 void SystemWindowScene::PostCheckContextTransparentTask()
307 {
308     checkContextTransparentTask_.Reset([weakThis = WeakClaim(this)]() {
309         auto self = weakThis.Upgrade();
310         CHECK_NULL_VOID(self);
311         CHECK_NULL_VOID(self->GetHost());
312         CHECK_NULL_VOID(self->session_);
313         if (self->session_->NeedCheckContextTransparent() && self->GetHost()->IsContextTransparent()) {
314             self->session_->NotifyContextTransparent();
315         }
316     });
317 
318     auto pipelineContext = PipelineContext::GetCurrentContext();
319     CHECK_NULL_VOID(pipelineContext);
320     auto taskExecutor = pipelineContext->GetTaskExecutor();
321     CHECK_NULL_VOID(taskExecutor);
322     taskExecutor->PostDelayedTask(std::move(checkContextTransparentTask_), TaskExecutor::TaskType::UI,
323         DELAY_TIME, "ArkUIWindowCheckContextTransparent");
324 }
325 
PostFaultInjectTask()326 void SystemWindowScene::PostFaultInjectTask()
327 {
328     auto task = ([weakThis = WeakClaim(this)]() {
329         auto self = weakThis.Upgrade();
330         CHECK_NULL_VOID(self);
331         auto host = self->GetHost();
332         CHECK_NULL_VOID(host);
333         auto renderContext = AceType::DynamicCast<NG::RosenRenderContext>(host->GetRenderContext());
334         renderContext->SetOpacity(0.0f);
335         host->MarkDirtyNode();
336     });
337 
338     auto pipelineContext = PipelineContext::GetCurrentContext();
339     CHECK_NULL_VOID(pipelineContext);
340     auto taskExecutor = pipelineContext->GetTaskExecutor();
341     CHECK_NULL_VOID(taskExecutor);
342     taskExecutor->PostDelayedTask(
343         std::move(task), TaskExecutor::TaskType::UI, DELAY_TIME, "ArkUIWindowFaultInject");
344 }
345 } // namespace OHOS::Ace::NG
346