1 /*
2  * Copyright (c) 2024 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/ui_extension/platform_pattern.h"
17 
18 #include <optional>
19 
20 #include "core/event/key_event.h"
21 #include "core/event/pointer_event.h"
22 
23 #include "adapter/ohos/entrance/ace_container.h"
24 #include "adapter/ohos/entrance/ace_extra_input_data.h"
25 #include "adapter/ohos/entrance/mmi_event_convertor.h"
26 #include "base/geometry/offset.h"
27 #include "base/utils/utils.h"
28 #include "core/common/container.h"
29 #include "core/components_ng/event/event_hub.h"
30 #include "core/components_ng/pattern/ui_extension/ui_extension_layout_algorithm.h"
31 #include "core/components_ng/pattern/window_scene/scene/window_pattern.h"
32 #include "core/components_ng/render/adapter/rosen_render_context.h"
33 #include "core/components_ng/render/adapter/rosen_window.h"
34 #include "core/event/ace_events.h"
35 #include "core/event/mouse_event.h"
36 #include "core/event/touch_event.h"
37 #include "core/pipeline/pipeline_context.h"
38 #include "core/pipeline_ng/pipeline_context.h"
39 
40 namespace OHOS::Ace::NG {
PlatformPattern(AceLogTag tag,int32_t platformId)41 PlatformPattern::PlatformPattern(AceLogTag tag, int32_t platformId)
42     : tag_(tag), platformId_(platformId)
43 {
44     PLATFORM_LOGI("The PlatformPattern is created");
45 }
46 
~PlatformPattern()47 PlatformPattern::~PlatformPattern()
48 {
49     PLATFORM_LOGI("The PlatformPattern is destroyed");
50 }
51 
CreateLayoutAlgorithm()52 RefPtr<LayoutAlgorithm> PlatformPattern::CreateLayoutAlgorithm()
53 {
54     return MakeRefPtr<UIExtensionLayoutAlgorithm>();
55 }
56 
GetFocusPattern() const57 FocusPattern PlatformPattern::GetFocusPattern() const
58 {
59     return { FocusType::NODE, true, FocusStyleType::FORCE_NONE };
60 }
61 
OnModifyDone()62 void PlatformPattern::OnModifyDone()
63 {
64     Pattern::OnModifyDone();
65     auto host = GetHost();
66     CHECK_NULL_VOID(host);
67     auto hub = host->GetEventHub<EventHub>();
68     CHECK_NULL_VOID(hub);
69     auto gestureHub = hub->GetOrCreateGestureEventHub();
70     CHECK_NULL_VOID(gestureHub);
71     InitTouchEvent(gestureHub);
72     auto inputHub = hub->GetOrCreateInputEventHub();
73     CHECK_NULL_VOID(inputHub);
74     InitMouseEvent(inputHub);
75     InitHoverEvent(inputHub);
76     auto focusHub = host->GetFocusHub();
77     CHECK_NULL_VOID(focusHub);
78     InitKeyEvent(focusHub);
79 }
80 
InitKeyEvent(const RefPtr<FocusHub> & focusHub)81 void PlatformPattern::InitKeyEvent(const RefPtr<FocusHub>& focusHub)
82 {
83     focusHub->SetOnFocusInternal([weak = WeakClaim(this)]() {
84         auto pattern = weak.Upgrade();
85         if (pattern) {
86             pattern->HandleFocusEvent();
87         }
88     });
89 
90     focusHub->SetOnBlurInternal([weak = WeakClaim(this)]() {
91         auto pattern = weak.Upgrade();
92         if (pattern) {
93             pattern->HandleBlurEvent();
94         }
95     });
96 
97     focusHub->SetOnClearFocusStateInternal([weak = WeakClaim(this)]() {
98         auto pattern = weak.Upgrade();
99         if (pattern) {
100             pattern->DispatchFocusActiveEvent(false);
101         }
102     });
103 
104     focusHub->SetOnPaintFocusStateInternal([weak = WeakClaim(this)]() -> bool {
105         auto pattern = weak.Upgrade();
106         if (pattern) {
107             pattern->DispatchFocusActiveEvent(true);
108             return true;
109         }
110         return false;
111     });
112 
113     focusHub->SetOnKeyEventInternal([wp = WeakClaim(this)](const KeyEvent& event) -> bool {
114         auto pattern = wp.Upgrade();
115         if (pattern) {
116             return pattern->HandleKeyEvent(event);
117         }
118         return false;
119     });
120 }
121 
InitTouchEvent(const RefPtr<GestureEventHub> & gestureHub)122 void PlatformPattern::InitTouchEvent(const RefPtr<GestureEventHub>& gestureHub)
123 {
124     if (touchEvent_) {
125         return;
126     }
127     auto callback = [weak = WeakClaim(this)](const TouchEventInfo& info) {
128         auto pattern = weak.Upgrade();
129         if (pattern) {
130             pattern->HandleTouchEvent(info);
131         }
132     };
133     if (touchEvent_) {
134         gestureHub->RemoveTouchEvent(touchEvent_);
135     }
136     touchEvent_ = MakeRefPtr<TouchEventImpl>(std::move(callback));
137     gestureHub->AddTouchEvent(touchEvent_);
138 }
139 
InitMouseEvent(const RefPtr<InputEventHub> & inputHub)140 void PlatformPattern::InitMouseEvent(const RefPtr<InputEventHub>& inputHub)
141 {
142     if (mouseEvent_) {
143         return;
144     }
145     auto callback = [weak = WeakClaim(this)](MouseInfo& info) {
146         auto pattern = weak.Upgrade();
147         if (pattern) {
148             pattern->HandleMouseEvent(info);
149         }
150     };
151     if (mouseEvent_) {
152         inputHub->RemoveOnMouseEvent(mouseEvent_);
153     }
154     mouseEvent_ = MakeRefPtr<InputEvent>(std::move(callback));
155     inputHub->AddOnMouseEvent(mouseEvent_);
156 }
157 
InitHoverEvent(const RefPtr<InputEventHub> & inputHub)158 void PlatformPattern::InitHoverEvent(const RefPtr<InputEventHub>& inputHub)
159 {
160     if (hoverEvent_) {
161         return;
162     }
163     auto callback = [weak = WeakClaim(this)](bool isHover) {
164         auto pattern = weak.Upgrade();
165         if (pattern) {
166             pattern->HandleHoverEvent(isHover);
167         }
168     };
169     if (hoverEvent_) {
170         inputHub->RemoveOnHoverEvent(hoverEvent_);
171     }
172     hoverEvent_ = MakeRefPtr<InputEvent>(std::move(callback));
173     inputHub->AddOnHoverEvent(hoverEvent_);
174 }
175 
HandleKeyEvent(const KeyEvent & event)176 bool PlatformPattern::HandleKeyEvent(const KeyEvent& event)
177 {
178     return false;
179 }
180 
HandleFocusEvent()181 void PlatformPattern::HandleFocusEvent()
182 {}
183 
HandleBlurEvent()184 void PlatformPattern::HandleBlurEvent()
185 {}
186 
HandleTouchEvent(const TouchEventInfo & info)187 void PlatformPattern::HandleTouchEvent(const TouchEventInfo& info)
188 {
189     if (info.GetSourceDevice() != SourceType::TOUCH) {
190         return;
191     }
192     const auto pointerEvent = info.GetPointerEvent();
193     CHECK_NULL_VOID(pointerEvent);
194     auto host = GetHost();
195     CHECK_NULL_VOID(host);
196     auto pipeline = PipelineBase::GetCurrentContext();
197     CHECK_NULL_VOID(pipeline);
198     Platform::CalculatePointerEvent(pointerEvent, host);
199     AceExtraInputData::InsertInterpolatePoints(info);
200     auto focusHub = host->GetFocusHub();
201     CHECK_NULL_VOID(focusHub);
202     focusHub->RequestFocusImmediately();
203     DispatchPointerEvent(pointerEvent);
204 }
205 
HandleMouseEvent(const MouseInfo & info)206 void PlatformPattern::HandleMouseEvent(const MouseInfo& info)
207 {
208     if (info.GetSourceDevice() != SourceType::MOUSE) {
209         return;
210     }
211     const auto pointerEvent = info.GetPointerEvent();
212     CHECK_NULL_VOID(pointerEvent);
213     lastPointerEvent_ = pointerEvent;
214     auto host = GetHost();
215     CHECK_NULL_VOID(host);
216     Platform::CalculatePointerEvent(pointerEvent, host);
217     if (info.GetAction() == MouseAction::PRESS) {
218         auto hub = host->GetFocusHub();
219         CHECK_NULL_VOID(hub);
220         hub->RequestFocusImmediately();
221     }
222     DispatchPointerEvent(pointerEvent);
223 }
224 
HandleHoverEvent(bool isHover)225 void PlatformPattern::HandleHoverEvent(bool isHover)
226 {
227     if (isHover) {
228         return;
229     }
230     CHECK_NULL_VOID(lastPointerEvent_);
231     lastPointerEvent_->SetPointerAction(MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW);
232     DispatchPointerEvent(lastPointerEvent_);
233 }
234 
HandleDragEvent(const PointerEvent & info)235 void PlatformPattern::HandleDragEvent(const PointerEvent& info)
236 {
237     const auto pointerEvent = info.rawPointerEvent;
238     CHECK_NULL_VOID(pointerEvent);
239     auto host = GetHost();
240     CHECK_NULL_VOID(host);
241     auto pipeline = PipelineBase::GetCurrentContext();
242     CHECK_NULL_VOID(pipeline);
243     Platform::CalculatePointerEvent(pointerEvent, host, true);
244     DispatchPointerEvent(pointerEvent);
245 }
246 
SetOnErrorCallback(const std::function<void (int32_t code,const std::string & name,const std::string & message)> && callback)247 void PlatformPattern::SetOnErrorCallback(
248     const std::function<void(int32_t code, const std::string& name, const std::string& message)>&& callback)
249 {
250     onErrorCallback_ = std::move(callback);
251     if (lastError_.code != 0) {
252         ErrorMsg error;
253         std::swap(lastError_, error);
254         FireOnErrorCallback(error.code, error.name, error.message);
255     }
256 }
257 
FireOnErrorCallback(int32_t code,const std::string & name,const std::string & message)258 void PlatformPattern::FireOnErrorCallback(
259     int32_t code, const std::string& name, const std::string& message)
260 {
261     PLATFORM_LOGI("FireOnError code: %{public}d, name: %{public}s, message: %{public}s",
262         code, name.c_str(), message.c_str());
263     if (onErrorCallback_) {
264         ContainerScope scope(instanceId_);
265         onErrorCallback_(code, name, message);
266         return;
267     }
268 
269     lastError_ = { code, name, message };
270 }
271 
OnMountToParentDone()272 void PlatformPattern::OnMountToParentDone()
273 {
274     auto frameNode = frameNode_.Upgrade();
275     CHECK_NULL_VOID(frameNode);
276     if (frameNode->GetNodeStatus() == NodeStatus::NORMAL_NODE) {
277         PLATFORM_LOGW("Frame node status is normal.");
278         return;
279     }
280 }
281 
GetNodeId()282 int32_t PlatformPattern::GetNodeId()
283 {
284     auto host = GetHost();
285     return host ? host->GetId() : -1;
286 }
287 
GetInstanceId()288 int32_t PlatformPattern::GetInstanceId()
289 {
290     return instanceId_;
291 }
292 } // namespace OHOS::Ace::NG
293