• 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/window_pattern.h"
17 
18 #include "session_manager/include/scene_session_manager.h"
19 #include "ui/rs_surface_node.h"
20 
21 #include "adapter/ohos/entrance/mmi_event_convertor.h"
22 #include "base/utils/system_properties.h"
23 #include "core/components_ng/image_provider/image_utils.h"
24 #include "core/components_ng/pattern/image/image_pattern.h"
25 #include "core/components_ng/pattern/window_scene/scene/window_event_process.h"
26 #include "core/components_ng/render/adapter/rosen_render_context.h"
27 #include "core/components_v2/inspector/inspector_constants.h"
28 
29 namespace OHOS::Ace::NG {
30 namespace {
31 constexpr uint32_t COLOR_BLACK = 0xff000000;
32 constexpr uint32_t COLOR_WHITE = 0xffffffff;
33 } // namespace
34 
35 class LifecycleListener : public Rosen::ILifecycleListener {
36 public:
LifecycleListener(const WeakPtr<WindowPattern> & windowPattern)37     explicit LifecycleListener(const WeakPtr<WindowPattern>& windowPattern) : windowPattern_(windowPattern) {}
38     virtual ~LifecycleListener() = default;
39 
OnConnect()40     void OnConnect() override
41     {
42         auto windowPattern = windowPattern_.Upgrade();
43         CHECK_NULL_VOID(windowPattern);
44         windowPattern->OnConnect();
45     }
46 
OnForeground()47     void OnForeground() override
48     {
49         auto windowPattern = windowPattern_.Upgrade();
50         CHECK_NULL_VOID(windowPattern);
51         windowPattern->OnForeground();
52     }
53 
OnBackground()54     void OnBackground() override
55     {
56         auto windowPattern = windowPattern_.Upgrade();
57         CHECK_NULL_VOID(windowPattern);
58         windowPattern->OnBackground();
59     }
60 
OnDisconnect()61     void OnDisconnect() override
62     {
63         auto windowPattern = windowPattern_.Upgrade();
64         CHECK_NULL_VOID(windowPattern);
65         windowPattern->OnDisconnect();
66     }
67 
OnExtensionDied()68     void OnExtensionDied() override
69     {
70         auto windowPattern = windowPattern_.Upgrade();
71         CHECK_NULL_VOID(windowPattern);
72         windowPattern->OnExtensionDied();
73     }
74 
75 private:
76     WeakPtr<WindowPattern> windowPattern_;
77 };
78 
RegisterLifecycleListener()79 void WindowPattern::RegisterLifecycleListener()
80 {
81     CHECK_NULL_VOID(session_);
82     lifecycleListener_ = std::make_shared<LifecycleListener>(WeakClaim(this));
83     session_->RegisterLifecycleListener(lifecycleListener_);
84 }
85 
UnregisterLifecycleListener()86 void WindowPattern::UnregisterLifecycleListener()
87 {
88     CHECK_NULL_VOID(session_);
89     session_->UnregisterLifecycleListener(lifecycleListener_);
90 }
91 
IsMainWindow() const92 bool WindowPattern::IsMainWindow() const
93 {
94     CHECK_NULL_RETURN(session_, false);
95     return session_->GetWindowType() == Rosen::WindowType::WINDOW_TYPE_APP_MAIN_WINDOW;
96 }
97 
InitContent()98 void WindowPattern::InitContent()
99 {
100     contentNode_ = FrameNode::CreateFrameNode(
101         V2::WINDOW_SCENE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>());
102     contentNode_->GetLayoutProperty()->UpdateMeasureType(MeasureType::MATCH_PARENT);
103     contentNode_->SetHitTestMode(HitTestMode::HTMNONE);
104 
105     CHECK_NULL_VOID(session_);
106     auto surfaceNode = session_->GetSurfaceNode();
107     if (surfaceNode) {
108         auto context = AceType::DynamicCast<NG::RosenRenderContext>(contentNode_->GetRenderContext());
109         CHECK_NULL_VOID(context);
110         context->SetRSNode(surfaceNode);
111     }
112 
113     auto host = GetHost();
114     CHECK_NULL_VOID(host);
115 
116     auto state = session_->GetSessionState();
117     auto bundleName = session_->GetSessionInfo().bundleName_;
118     LOGI("Session state: %{public}u, bundle name: %{public}s", state, bundleName.c_str());
119     if (state == Rosen::SessionState::STATE_DISCONNECT) {
120         if (!HasStartingPage()) {
121             return;
122         }
123         if (session_->GetShowRecent()) {
124             CreateSnapshotNode();
125             host->AddChild(snapshotNode_);
126             return;
127         }
128         CreateStartingNode();
129         host->AddChild(startingNode_);
130         return;
131     }
132 
133     if (state == Rosen::SessionState::STATE_BACKGROUND && session_->GetBufferAvailable()) {
134         CreateSnapshotNode();
135         host->AddChild(snapshotNode_);
136         return;
137     }
138 
139     host->AddChild(contentNode_);
140     if (!session_->GetBufferAvailable()) {
141         CreateStartingNode();
142         host->AddChild(startingNode_);
143         if (surfaceNode) {
144             surfaceNode->SetBufferAvailableCallback(callback_);
145         }
146     }
147 }
148 
CreateStartingNode()149 void WindowPattern::CreateStartingNode()
150 {
151     startingNode_ = FrameNode::CreateFrameNode(
152         V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ImagePattern>());
153     auto imageLayoutProperty = startingNode_->GetLayoutProperty<ImageLayoutProperty>();
154     imageLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
155     startingNode_->SetHitTestMode(HitTestMode::HTMNONE);
156 
157     std::string startupPagePath;
158     auto backgroundColor = SystemProperties::GetColorMode() == ColorMode::DARK ? COLOR_BLACK : COLOR_WHITE;
159     auto sessionInfo = session_->GetSessionInfo();
160     Rosen::SceneSessionManager::GetInstance().GetStartPage(sessionInfo, startupPagePath, backgroundColor);
161     LOGI("startup page path %{public}s, background color %{public}x", startupPagePath.c_str(), backgroundColor);
162 
163     startingNode_->GetRenderContext()->UpdateBackgroundColor(Color(backgroundColor));
164     imageLayoutProperty->UpdateImageSourceInfo(
165         ImageSourceInfo(startupPagePath, sessionInfo.bundleName_, sessionInfo.moduleName_));
166     imageLayoutProperty->UpdateImageFit(ImageFit::NONE);
167     startingNode_->MarkModifyDone();
168 }
169 
CreateSnapshotNode(std::shared_ptr<Media::PixelMap> snapshot)170 void WindowPattern::CreateSnapshotNode(std::shared_ptr<Media::PixelMap> snapshot)
171 {
172     snapshotNode_ = FrameNode::CreateFrameNode(
173         V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ImagePattern>());
174     auto imageLayoutProperty = snapshotNode_->GetLayoutProperty<ImageLayoutProperty>();
175     imageLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
176     snapshotNode_->SetHitTestMode(HitTestMode::HTMNONE);
177 
178     auto backgroundColor = SystemProperties::GetColorMode() == ColorMode::DARK ? COLOR_BLACK : COLOR_WHITE;
179     snapshotNode_->GetRenderContext()->UpdateBackgroundColor(Color(backgroundColor));
180     CHECK_NULL_VOID(session_);
181     if (snapshot) {
182         auto pixelMap = PixelMap::CreatePixelMap(&snapshot);
183         CHECK_NULL_VOID(pixelMap);
184         imageLayoutProperty->UpdateImageSourceInfo(ImageSourceInfo(pixelMap));
185     } else {
186         CHECK_NULL_VOID(session_->GetScenePersistence());
187         ImageSourceInfo sourceInfo("file:/" + session_->GetScenePersistence()->GetSnapshotFilePath());
188         imageLayoutProperty->UpdateImageSourceInfo(sourceInfo);
189         auto pipelineContext = PipelineContext::GetCurrentContext();
190         CHECK_NULL_VOID(pipelineContext);
191         auto imageCache = pipelineContext->GetImageCache();
192         CHECK_NULL_VOID(imageCache);
193         auto snapshotSize = session_->GetScenePersistence()->GetSnapshotSize();
194         auto cacheKey = ImageUtils::GenerateImageKey(sourceInfo, SizeF(snapshotSize.first, snapshotSize.second));
195         imageCache->ClearCacheImage(cacheKey);
196     }
197     imageLayoutProperty->UpdateImageFit(ImageFit::FILL);
198     snapshotNode_->MarkModifyDone();
199 }
200 
OnAttachToFrameNode()201 void WindowPattern::OnAttachToFrameNode()
202 {
203     InitContent();
204 
205     auto host = GetHost();
206     CHECK_NULL_VOID(host);
207     host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
208 }
209 
DispatchPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)210 void WindowPattern::DispatchPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
211 {
212     CHECK_NULL_VOID(session_);
213     CHECK_NULL_VOID(pointerEvent);
214     session_->TransferPointerEvent(pointerEvent);
215 #ifdef ENABLE_DRAG_FRAMEWORK
216     if (pointerEvent->GetPointerAction() >= MMI::PointerEvent::POINTER_ACTION_PULL_DOWN &&
217         pointerEvent->GetPointerAction() <= MMI::PointerEvent::POINTER_ACTION_PULL_UP) {
218         auto pipeline = PipelineContext::GetCurrentContext();
219         if (pipeline) {
220             auto manager = pipeline->GetDragDropManager();
221             CHECK_NULL_VOID(manager);
222             manager->SetIsWindowConsumed(true);
223         }
224     }
225 #endif // ENABLE_DRAG_FRAMEWORK
226 }
227 
DispatchKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent)228 void WindowPattern::DispatchKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent)
229 {
230     CHECK_NULL_VOID(session_);
231     CHECK_NULL_VOID(keyEvent);
232     session_->TransferKeyEvent(keyEvent);
233 }
234 
DispatchKeyEventForConsumed(const std::shared_ptr<MMI::KeyEvent> & keyEvent,bool & isConsumed)235 void WindowPattern::DispatchKeyEventForConsumed(const std::shared_ptr<MMI::KeyEvent>& keyEvent, bool& isConsumed)
236 {
237     CHECK_NULL_VOID(session_);
238     session_->TransferKeyEventForConsumed(keyEvent, isConsumed);
239 }
240 
DisPatchFocusActiveEvent(bool isFocusActive)241 void WindowPattern::DisPatchFocusActiveEvent(bool isFocusActive)
242 {
243     CHECK_NULL_VOID(session_);
244     session_->TransferFocusActiveEvent(isFocusActive);
245 }
246 
InitTouchEvent(const RefPtr<GestureEventHub> & gestureHub)247 void WindowPattern::InitTouchEvent(const RefPtr<GestureEventHub>& gestureHub)
248 {
249     if (touchEvent_) {
250         return;
251     }
252     auto callback = [weak = WeakClaim(this)](const TouchEventInfo& info) {
253         auto pattern = weak.Upgrade();
254         if (pattern) {
255             pattern->HandleTouchEvent(info);
256         }
257     };
258     if (touchEvent_) {
259         gestureHub->RemoveTouchEvent(touchEvent_);
260     }
261     touchEvent_ = MakeRefPtr<TouchEventImpl>(std::move(callback));
262     gestureHub->AddTouchEvent(touchEvent_);
263 }
264 
InitMouseEvent(const RefPtr<InputEventHub> & inputHub)265 void WindowPattern::InitMouseEvent(const RefPtr<InputEventHub>& inputHub)
266 {
267     if (mouseEvent_) {
268         return;
269     }
270     auto callback = [weak = WeakClaim(this)](MouseInfo& info) {
271         auto pattern = weak.Upgrade();
272         if (pattern) {
273             pattern->HandleMouseEvent(info);
274         }
275     };
276     if (mouseEvent_) {
277         inputHub->RemoveOnMouseEvent(mouseEvent_);
278     }
279     mouseEvent_ = MakeRefPtr<InputEvent>(std::move(callback));
280     inputHub->AddOnMouseEvent(mouseEvent_);
281 }
282 
HandleTouchEvent(const TouchEventInfo & info)283 void WindowPattern::HandleTouchEvent(const TouchEventInfo& info)
284 {
285     LOGD("WindowPattern HandleTouchEvent enter");
286     const auto pointerEvent = info.GetPointerEvent();
287     CHECK_NULL_VOID(pointerEvent);
288     if (IsFilterTouchEvent(pointerEvent)) {
289         return;
290     }
291     auto host = GetHost();
292     CHECK_NULL_VOID_NOLOG(host);
293     auto selfGlobalOffset = host->GetTransformRelativeOffset();
294     auto scale = host->GetTransformScale();
295     Platform::CalculateWindowCoordinate(selfGlobalOffset, pointerEvent, scale);
296     SetWindowSceneConsumed(pointerEvent->GetPointerAction());
297     AdapterRotation(pointerEvent);
298     DispatchPointerEvent(pointerEvent);
299 }
300 
AdapterRotation(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)301 void WindowPattern::AdapterRotation(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
302 {
303     auto& translateCfg = NGGestureRecognizer::GetGlobalTransCfg();
304     auto& translateIds = NGGestureRecognizer::GetGlobalTransIds();
305     CHECK_NULL_VOID(pointerEvent);
306     auto frameNode = GetHost();
307     CHECK_NULL_VOID(frameNode);
308     auto translateIter = translateIds.find(frameNode->GetId());
309     if (translateIter == translateIds.end()) {
310         return;
311     }
312     int32_t udegree = 0;
313     while (translateIter != translateIds.end()) {
314         int32_t translateId = translateIter->second.parentId;
315         auto translateCfgIter = translateCfg.find(translateId);
316         if (translateCfgIter != translateCfg.end() && translateCfgIter->second.degree != 0) {
317             udegree = static_cast<int32_t>(translateCfgIter->second.degree);
318             break;
319         }
320         translateIter = translateIds.find(translateId);
321     }
322     udegree = udegree % 360;
323     if (udegree == -1 || udegree == 0) {
324         return;
325     }
326     udegree = udegree < 0 ? udegree + 360 : udegree;
327     int32_t pointerId = pointerEvent->GetPointerId();
328     MMI::PointerEvent::PointerItem item;
329     bool ret = pointerEvent->GetPointerItem(pointerId, item);
330     if (!ret) {
331         return;
332     }
333     int32_t originWindowX = item.GetWindowX();
334     int32_t originWindowY = item.GetWindowY();
335     auto host = GetHost();
336     CHECK_NULL_VOID(host);
337     auto rect = host->GetPaintRectWithTransform();
338     int32_t width = static_cast<int32_t>(rect.Width());
339     int32_t height = static_cast<int32_t>(rect.Height());
340 
341     if (udegree == 90) {
342         item.SetWindowX(originWindowY);
343         item.SetWindowY(height - originWindowX);
344     }
345     if (udegree == 180) {
346         item.SetWindowX(width - originWindowX);
347         item.SetWindowY(height - originWindowY);
348     }
349     if (udegree == 270) {
350         item.SetWindowX(width - originWindowY);
351         item.SetWindowY(originWindowX);
352     }
353     pointerEvent->UpdatePointerItem(pointerId, item);
354     LOGD("WindowPattern AdapterRotation udegree:%{public}d, windowX:%{public}d, windowY:%{public}d", udegree,
355         item.GetWindowX(), item.GetWindowY());
356 }
357 
IsFilterTouchEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)358 bool WindowPattern::IsFilterTouchEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
359 {
360     return (pointerEvent->GetSourceType() == MMI::PointerEvent::SOURCE_TYPE_MOUSE &&
361         (pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN ||
362         pointerEvent->GetButtonId() == MMI::PointerEvent::BUTTON_NONE)) ||
363         (pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_PULL_MOVE ||
364         pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_PULL_UP);
365 }
366 
HandleMouseEvent(const MouseInfo & info)367 void WindowPattern::HandleMouseEvent(const MouseInfo& info)
368 {
369     LOGD("WindowPattern HandleMouseEvent enter");
370     const auto pointerEvent = info.GetPointerEvent();
371     CHECK_NULL_VOID(pointerEvent);
372     if (IsFilterMouseEvent(pointerEvent)) {
373         return;
374     }
375     auto host = GetHost();
376     CHECK_NULL_VOID_NOLOG(host);
377     auto selfGlobalOffset = host->GetTransformRelativeOffset();
378     auto scale = host->GetTransformScale();
379     Platform::CalculateWindowCoordinate(selfGlobalOffset, pointerEvent, scale);
380     int32_t action = pointerEvent->GetPointerAction();
381     if ((action == MMI::PointerEvent::POINTER_ACTION_MOVE &&
382         pointerEvent->GetButtonId() == MMI::PointerEvent::BUTTON_NONE) ||
383         (action == MMI::PointerEvent::POINTER_ACTION_ENTER_WINDOW)) {
384         DelayedSingleton<WindowEventProcess>::GetInstance()->ProcessWindowMouseEvent(
385             AceType::DynamicCast<WindowNode>(host), pointerEvent);
386     }
387     if (action == MMI::PointerEvent::POINTER_ACTION_PULL_MOVE) {
388         DelayedSingleton<WindowEventProcess>::GetInstance()->ProcessWindowDragEvent(
389             AceType::DynamicCast<WindowNode>(host), pointerEvent);
390     }
391     if ((pointerEvent->GetSourceType() == MMI::PointerEvent::SOURCE_TYPE_MOUSE) &&
392         (action == MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW)) {
393         DelayedSingleton<WindowEventProcess>::GetInstance()->CleanWindowMouseRecord();
394     }
395     if (action == MMI::PointerEvent::POINTER_ACTION_PULL_UP) {
396         DelayedSingleton<WindowEventProcess>::GetInstance()->CleanWindowDragEvent();
397     }
398     SetWindowSceneConsumed(action);
399     DispatchPointerEvent(pointerEvent);
400 }
401 
IsFilterMouseEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)402 bool WindowPattern::IsFilterMouseEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
403 {
404     int32_t pointerAction = pointerEvent->GetPointerAction();
405     if ((pointerEvent->GetSourceType() == MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN) &&
406         (pointerAction != MMI::PointerEvent::POINTER_ACTION_PULL_MOVE) &&
407         (pointerAction != MMI::PointerEvent::POINTER_ACTION_PULL_UP)) {
408         return true;
409     }
410     return pointerEvent->GetButtonId() == MMI::PointerEvent::MOUSE_BUTTON_LEFT &&
411         (pointerAction == MMI::PointerEvent::POINTER_ACTION_MOVE ||
412         pointerAction == MMI::PointerEvent::POINTER_ACTION_BUTTON_UP);
413 }
414 
OnModifyDone()415 void WindowPattern::OnModifyDone()
416 {
417     Pattern::OnModifyDone();
418     auto host = GetHost();
419     CHECK_NULL_VOID(host);
420     auto hub = host->GetEventHub<EventHub>();
421     CHECK_NULL_VOID(hub);
422     auto gestureHub = hub->GetOrCreateGestureEventHub();
423     CHECK_NULL_VOID(gestureHub);
424     InitTouchEvent(gestureHub);
425     auto inputHub = hub->GetOrCreateInputEventHub();
426     CHECK_NULL_VOID(inputHub);
427     InitMouseEvent(inputHub);
428 }
429 
TransferFocusState(bool focusState)430 void WindowPattern::TransferFocusState(bool focusState)
431 {
432     CHECK_NULL_VOID(session_);
433     session_->TransferFocusStateEvent(focusState);
434 }
435 
GetHotAreas()436 std::vector<Rosen::Rect> WindowPattern::GetHotAreas()
437 {
438     if (session_ == nullptr) {
439         return std::vector<Rosen::Rect>();
440     }
441     return session_->GetTouchHotAreas();
442 }
443 
SetWindowSceneConsumed(int32_t action)444 void WindowPattern::SetWindowSceneConsumed(int32_t action)
445 {
446     auto pipeline = PipelineContext::GetCurrentContext();
447     if (pipeline) {
448         if (action == MMI::PointerEvent::POINTER_ACTION_DOWN ||
449             action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) {
450             pipeline->SetWindowSceneConsumed(true);
451         }
452         if (action == MMI::PointerEvent::POINTER_ACTION_UP ||
453             action == MMI::PointerEvent::POINTER_ACTION_BUTTON_UP ||
454             action == MMI::PointerEvent::POINTER_ACTION_PULL_UP) {
455             pipeline->SetWindowSceneConsumed(false);
456         }
457     }
458 }
459 } // namespace OHOS::Ace::NG
460