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->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->SetIsNodeNeedKey(true);
84 focusHub->SetOnFocusInternal([weak = WeakClaim(this)]() {
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 auto pipeline = PipelineBase::GetCurrentContext();
198 CHECK_NULL_VOID(pipeline);
199 auto newPointerEvent = PlatformUtils::CopyPointerEventWithExtraProperty(pointerEvent, tag_);
200 CHECK_NULL_VOID(newPointerEvent);
201 Platform::CalculatePointerEvent(newPointerEvent, host);
202 AceExtraInputData::InsertInterpolatePoints(info);
203 const auto& changedTouches = info.GetChangedTouches();
204 if (!changedTouches.empty() && changedTouches.back().GetTouchType() == TouchType::DOWN) {
205 auto focusHub = host->GetFocusHub();
206 CHECK_NULL_VOID(focusHub);
207 focusHub->RequestFocusImmediately();
208 }
209 DispatchPointerEvent(newPointerEvent);
210 }
211
HandleMouseEvent(const MouseInfo & info)212 void PlatformPattern::HandleMouseEvent(const MouseInfo& info)
213 {
214 if (info.GetSourceDevice() != SourceType::MOUSE) {
215 return;
216 }
217 const auto pointerEvent = info.GetPointerEvent();
218 CHECK_NULL_VOID(pointerEvent);
219 lastPointerEvent_ = PlatformUtils::CopyPointerEventWithExtraProperty(pointerEvent, tag_);
220 auto host = GetHost();
221 CHECK_NULL_VOID(host);
222 Platform::CalculatePointerEvent(pointerEvent, host);
223 if (info.GetAction() == MouseAction::PRESS) {
224 auto hub = host->GetFocusHub();
225 CHECK_NULL_VOID(hub);
226 hub->RequestFocusImmediately();
227 }
228 DispatchPointerEvent(pointerEvent);
229 }
230
HandleHoverEvent(bool isHover)231 void PlatformPattern::HandleHoverEvent(bool isHover)
232 {
233 if (isHover) {
234 return;
235 }
236 CHECK_NULL_VOID(lastPointerEvent_);
237 lastPointerEvent_->SetPointerAction(MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW);
238 DispatchPointerEvent(lastPointerEvent_);
239 }
240
HandleDragEvent(const DragPointerEvent & info)241 void PlatformPattern::HandleDragEvent(const DragPointerEvent& info)
242 {
243 const auto pointerEvent = info.rawPointerEvent;
244 CHECK_NULL_VOID(pointerEvent);
245 auto host = GetHost();
246 CHECK_NULL_VOID(host);
247 auto pipeline = PipelineBase::GetCurrentContext();
248 CHECK_NULL_VOID(pipeline);
249 Platform::CalculatePointerEvent(pointerEvent, host, true);
250 DispatchPointerEvent(pointerEvent);
251 }
252
SetOnErrorCallback(const std::function<void (int32_t code,const std::string & name,const std::string & message)> && callback)253 void PlatformPattern::SetOnErrorCallback(
254 const std::function<void(int32_t code, const std::string& name, const std::string& message)>&& callback)
255 {
256 onErrorCallback_ = std::move(callback);
257 if (lastError_.code != 0) {
258 ErrorMsg error;
259 std::swap(lastError_, error);
260 FireOnErrorCallback(error.code, error.name, error.message);
261 }
262 }
263
FireOnErrorCallback(int32_t code,const std::string & name,const std::string & message)264 void PlatformPattern::FireOnErrorCallback(
265 int32_t code, const std::string& name, const std::string& message)
266 {
267 PLATFORM_LOGI("FireOnError code: %{public}d, name: %{public}s, message: %{public}s",
268 code, name.c_str(), message.c_str());
269 if (onErrorCallback_) {
270 ContainerScope scope(instanceId_);
271 onErrorCallback_(code, name, message);
272 return;
273 }
274
275 lastError_ = { code, name, message };
276 }
277
OnMountToParentDone()278 void PlatformPattern::OnMountToParentDone()
279 {
280 auto frameNode = frameNode_.Upgrade();
281 CHECK_NULL_VOID(frameNode);
282 if (frameNode->GetNodeStatus() == NodeStatus::NORMAL_NODE) {
283 PLATFORM_LOGW("Frame node status is normal.");
284 return;
285 }
286 }
287
GetNodeId()288 int32_t PlatformPattern::GetNodeId()
289 {
290 auto host = GetHost();
291 return host ? host->GetId() : -1;
292 }
293
GetInstanceId()294 int32_t PlatformPattern::GetInstanceId()
295 {
296 return instanceId_;
297 }
298 } // namespace OHOS::Ace::NG
299