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/utils/utils.h"
27 #include "core/common/container.h"
28 #include "core/components_ng/event/event_hub.h"
29 #include "core/components_ng/pattern/ui_extension/platform_utils.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->GetOrCreateEventHub<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->SetIsNodeNeedKey(true);
84 focusHub->SetOnFocusInternal([weak = WeakClaim(this)](FocusReason reason) {
85 auto pattern = weak.Upgrade();
86 if (pattern) {
87 pattern->HandleFocusEvent();
88 }
89 });
90
91 focusHub->SetOnBlurInternal([weak = WeakClaim(this)]() {
92 auto pattern = weak.Upgrade();
93 if (pattern) {
94 pattern->HandleBlurEvent();
95 }
96 });
97
98 focusHub->SetOnClearFocusStateInternal([weak = WeakClaim(this)]() {
99 auto pattern = weak.Upgrade();
100 if (pattern) {
101 pattern->DispatchFocusActiveEvent(false);
102 }
103 });
104
105 focusHub->SetOnPaintFocusStateInternal([weak = WeakClaim(this)]() -> bool {
106 auto pattern = weak.Upgrade();
107 if (pattern) {
108 pattern->DispatchFocusActiveEvent(true);
109 return true;
110 }
111 return false;
112 });
113
114 focusHub->SetOnKeyEventInternal([wp = WeakClaim(this)](const KeyEvent& event) -> bool {
115 auto pattern = wp.Upgrade();
116 if (pattern) {
117 return pattern->HandleKeyEvent(event);
118 }
119 return false;
120 });
121 }
122
InitTouchEvent(const RefPtr<GestureEventHub> & gestureHub)123 void PlatformPattern::InitTouchEvent(const RefPtr<GestureEventHub>& gestureHub)
124 {
125 if (touchEvent_) {
126 return;
127 }
128 auto callback = [weak = WeakClaim(this)](const TouchEventInfo& info) {
129 auto pattern = weak.Upgrade();
130 if (pattern) {
131 pattern->HandleTouchEvent(info);
132 }
133 };
134 if (touchEvent_) {
135 gestureHub->RemoveTouchEvent(touchEvent_);
136 }
137 touchEvent_ = MakeRefPtr<TouchEventImpl>(std::move(callback));
138 gestureHub->AddTouchEvent(touchEvent_);
139 }
140
InitMouseEvent(const RefPtr<InputEventHub> & inputHub)141 void PlatformPattern::InitMouseEvent(const RefPtr<InputEventHub>& inputHub)
142 {
143 if (mouseEvent_) {
144 return;
145 }
146 auto callback = [weak = WeakClaim(this)](MouseInfo& info) {
147 auto pattern = weak.Upgrade();
148 if (pattern) {
149 pattern->HandleMouseEvent(info);
150 }
151 };
152 if (mouseEvent_) {
153 inputHub->RemoveOnMouseEvent(mouseEvent_);
154 }
155 mouseEvent_ = MakeRefPtr<InputEvent>(std::move(callback));
156 inputHub->AddOnMouseEvent(mouseEvent_);
157 }
158
InitHoverEvent(const RefPtr<InputEventHub> & inputHub)159 void PlatformPattern::InitHoverEvent(const RefPtr<InputEventHub>& inputHub)
160 {
161 if (hoverEvent_) {
162 return;
163 }
164 auto callback = [weak = WeakClaim(this)](bool isHover) {
165 auto pattern = weak.Upgrade();
166 if (pattern) {
167 pattern->HandleHoverEvent(isHover);
168 }
169 };
170 if (hoverEvent_) {
171 inputHub->RemoveOnHoverEvent(hoverEvent_);
172 }
173 hoverEvent_ = MakeRefPtr<InputEvent>(std::move(callback));
174 inputHub->AddOnHoverEvent(hoverEvent_);
175 }
176
HandleKeyEvent(const KeyEvent & event)177 bool PlatformPattern::HandleKeyEvent(const KeyEvent& event)
178 {
179 return false;
180 }
181
HandleFocusEvent()182 void PlatformPattern::HandleFocusEvent()
183 {}
184
HandleBlurEvent()185 void PlatformPattern::HandleBlurEvent()
186 {}
187
HandleTouchEvent(const TouchEventInfo & info)188 void PlatformPattern::HandleTouchEvent(const TouchEventInfo& info)
189 {
190 if (info.GetSourceDevice() != SourceType::TOUCH) {
191 return;
192 }
193 const auto pointerEvent = info.GetPointerEvent();
194 CHECK_NULL_VOID(pointerEvent);
195 auto host = GetHost();
196 CHECK_NULL_VOID(host);
197 const auto& changedTouches = info.GetChangedTouches();
198 if (!changedTouches.empty() && changedTouches.back().GetTouchType() == TouchType::DOWN) {
199 auto focusHub = host->GetFocusHub();
200 CHECK_NULL_VOID(focusHub);
201 focusHub->RequestFocusImmediately();
202 }
203
204 if (tag_ != AceLogTag::ACE_DYNAMIC_COMPONENT) {
205 bool ret = HandleTouchEvent(pointerEvent);
206 if (ret) {
207 AceExtraInputData::InsertInterpolatePoints(info);
208 }
209 }
210 }
211
HandleTouchEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)212 bool PlatformPattern::HandleTouchEvent(
213 const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
214 {
215 CHECK_NULL_RETURN(pointerEvent, false);
216 auto host = GetHost();
217 CHECK_NULL_RETURN(host, false);
218 auto newPointerEvent = PlatformUtils::CopyPointerEventWithExtraProperty(pointerEvent, tag_);
219 CHECK_NULL_RETURN(newPointerEvent, false);
220 Platform::CalculatePointerEvent(newPointerEvent, host);
221 DispatchPointerEvent(newPointerEvent);
222 return true;
223 }
224
HandleMouseEvent(const MouseInfo & info)225 void PlatformPattern::HandleMouseEvent(const MouseInfo& info)
226 {
227 if (info.GetSourceDevice() != SourceType::MOUSE) {
228 return;
229 }
230 const auto pointerEvent = info.GetPointerEvent();
231 CHECK_NULL_VOID(pointerEvent);
232 lastPointerEvent_ = PlatformUtils::CopyPointerEventWithExtraProperty(pointerEvent, tag_);
233 auto host = GetHost();
234 CHECK_NULL_VOID(host);
235 Platform::CalculatePointerEvent(pointerEvent, host);
236 if (info.GetAction() == MouseAction::PRESS) {
237 auto hub = host->GetFocusHub();
238 CHECK_NULL_VOID(hub);
239 hub->RequestFocusImmediately();
240 }
241 DispatchPointerEvent(pointerEvent);
242 }
243
HandleHoverEvent(bool isHover)244 void PlatformPattern::HandleHoverEvent(bool isHover)
245 {
246 if (isHover) {
247 return;
248 }
249 CHECK_NULL_VOID(lastPointerEvent_);
250 lastPointerEvent_->SetPointerAction(MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW);
251 DispatchPointerEvent(lastPointerEvent_);
252 }
253
HandleDragEvent(const DragPointerEvent & info)254 void PlatformPattern::HandleDragEvent(const DragPointerEvent& info)
255 {
256 const auto pointerEvent = info.rawPointerEvent;
257 CHECK_NULL_VOID(pointerEvent);
258 auto host = GetHost();
259 CHECK_NULL_VOID(host);
260 auto pipeline = PipelineBase::GetCurrentContext();
261 CHECK_NULL_VOID(pipeline);
262 Platform::CalculatePointerEvent(pointerEvent, host, true);
263 DispatchPointerEvent(pointerEvent);
264 }
265
SetOnErrorCallback(const std::function<void (int32_t code,const std::string & name,const std::string & message)> && callback)266 void PlatformPattern::SetOnErrorCallback(
267 const std::function<void(int32_t code, const std::string& name, const std::string& message)>&& callback)
268 {
269 onErrorCallback_ = std::move(callback);
270 if (lastError_.code != 0) {
271 ErrorMsg error;
272 std::swap(lastError_, error);
273 FireOnErrorCallback(error.code, error.name, error.message);
274 }
275 }
276
FireOnErrorCallback(int32_t code,const std::string & name,const std::string & message)277 void PlatformPattern::FireOnErrorCallback(
278 int32_t code, const std::string& name, const std::string& message)
279 {
280 PLATFORM_LOGI("FireOnError code: %{public}d, name: %{public}s, message: %{public}s",
281 code, name.c_str(), message.c_str());
282 if (onErrorCallback_) {
283 ContainerScope scope(instanceId_);
284 onErrorCallback_(code, name, message);
285 return;
286 }
287
288 lastError_ = { code, name, message };
289 }
290
OnMountToParentDone()291 void PlatformPattern::OnMountToParentDone()
292 {
293 auto frameNode = frameNode_.Upgrade();
294 CHECK_NULL_VOID(frameNode);
295 if (frameNode->GetNodeStatus() == NodeStatus::NORMAL_NODE) {
296 PLATFORM_LOGW("Frame node status is normal.");
297 return;
298 }
299 }
300
GetNodeId()301 int32_t PlatformPattern::GetNodeId()
302 {
303 auto host = GetHost();
304 return host ? host->GetId() : -1;
305 }
306
GetInstanceId()307 int32_t PlatformPattern::GetInstanceId()
308 {
309 return instanceId_;
310 }
311 } // namespace OHOS::Ace::NG
312