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