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 "bridge/cj_frontend/frontend/cj_frontend.h"
17
18 #include "bridge/cj_frontend/frontend/cj_page_router.h"
19 #include "bridge/js_frontend/js_ace_page.h"
20 #include "core/components_ng/pattern/stage/page_pattern.h"
21 #include "core/gestures/swipe_recognizer.h"
22 #include "core/components/navigator/navigator_component.h"
23
24 namespace OHOS::Ace::Framework {
InternalInitialize()25 void CJFrontend::InternalInitialize()
26 {
27 LOGE("CJFrontend InternalInitialize begin.");
28 classicRouter_ = MakeRefPtr<CJPageRouter>(WeakClaim(this));
29 pageRouterManager_ = classicRouter_;
30 pageRouterManager_->SetManifestParser(manifestParser_);
31 handler_ = MakeRefPtr<CJEventHandler>(WeakClaim(this));
32 }
33
AttachPipelineContext(const RefPtr<PipelineBase> & context)34 void CJFrontend::AttachPipelineContext(const RefPtr<PipelineBase>& context)
35 {
36 CJFrontendAbstract::AttachPipelineContext(context);
37 auto pipeline = DynamicCast<PipelineContext>(context);
38 if (pipeline) {
39 pipeline->RegisterEventHandler(handler_);
40 }
41 }
42
43 namespace {
44
45 /*
46 * NOTE:
47 * This function is needed to copy the values from BaseEventInfo
48 * It is observed, that the owner of BaseEventInfo will delete the pointer before it is ultimately
49 * processed by the EventMarker callback. In order to avoid this, a copy of all data needs to be made.
50 */
CopyEventInfo(const BaseEventInfo & info)51 std::shared_ptr<BaseEventInfo> CopyEventInfo(const BaseEventInfo& info)
52 {
53 const auto* touchInfo = TypeInfoHelper::DynamicCast<TouchEventInfo>(&info);
54 if (touchInfo != nullptr) {
55 return std::make_shared<TouchEventInfo>(*touchInfo);
56 }
57
58 const auto* dragStartInfo = TypeInfoHelper::DynamicCast<DragStartInfo>(&info);
59 if (dragStartInfo != nullptr) {
60 return std::make_shared<DragStartInfo>(*dragStartInfo);
61 }
62
63 const auto* dragUpdateInfo = TypeInfoHelper::DynamicCast<DragUpdateInfo>(&info);
64 if (dragUpdateInfo != nullptr) {
65 return std::make_shared<DragUpdateInfo>(*dragUpdateInfo);
66 }
67
68 const auto* dragEndInfo = TypeInfoHelper::DynamicCast<DragEndInfo>(&info);
69 if (dragEndInfo != nullptr) {
70 return std::make_shared<DragEndInfo>(*dragEndInfo);
71 }
72
73 const auto* clickInfo = TypeInfoHelper::DynamicCast<ClickInfo>(&info);
74 if (clickInfo != nullptr) {
75 return std::make_shared<ClickInfo>(*clickInfo);
76 }
77 return nullptr;
78 }
79
TouchInfoToString(const BaseEventInfo & info,std::string & eventParam)80 void TouchInfoToString(const BaseEventInfo& info, std::string& eventParam)
81 {
82 eventParam.append("{\"touches\":[{");
83 const auto touchInfo = TypeInfoHelper::DynamicCast<TouchEventInfo>(&info);
84 if (touchInfo) {
85 auto touchList = touchInfo->GetTouches();
86 for (const auto& location : touchList) {
87 auto globalLocation = location.GetGlobalLocation();
88 eventParam.append("\"globalX\":")
89 .append(std::to_string(globalLocation.GetX()))
90 .append(",\"globalY\":")
91 .append(std::to_string(globalLocation.GetY()))
92 .append(",");
93 auto localLocation = location.GetLocalLocation();
94 eventParam.append("\"localX\":")
95 .append(std::to_string(localLocation.GetX()))
96 .append(",\"localY\":")
97 .append(std::to_string(localLocation.GetY()))
98 .append(",");
99 eventParam.append("\"size\":").append(std::to_string(location.GetSize())).append(",");
100 }
101 if (eventParam.back() == ',') {
102 eventParam.pop_back();
103 }
104 eventParam.append("}],\"changedTouches\":[{");
105 auto changeTouch = touchInfo->GetChangedTouches();
106 for (const auto& change : changeTouch) {
107 auto globalLocation = change.GetGlobalLocation();
108 eventParam.append("\"globalX\":")
109 .append(std::to_string(globalLocation.GetX()))
110 .append(",\"globalY\":")
111 .append(std::to_string(globalLocation.GetY()))
112 .append(",");
113 auto localLocation = change.GetLocalLocation();
114 eventParam.append("\"localX\":")
115 .append(std::to_string(localLocation.GetX()))
116 .append(",\"localY\":")
117 .append(std::to_string(localLocation.GetY()))
118 .append(",");
119 eventParam.append("\"size\":").append(std::to_string(change.GetSize())).append(",");
120 }
121 if (eventParam.back() == ',') {
122 eventParam.pop_back();
123 }
124 }
125 eventParam.append("}]}");
126 }
127
MouseInfoToString(const BaseEventInfo & info,std::string & eventParam)128 void MouseInfoToString(const BaseEventInfo& info, std::string& eventParam)
129 {
130 const auto mouseInfo = TypeInfoHelper::DynamicCast<MouseEventInfo>(&info);
131 eventParam.append("{\"mouse\":{");
132 if (mouseInfo) {
133 auto globalMouse = mouseInfo->GetGlobalMouse();
134 eventParam.append("\"globalX\":")
135 .append(std::to_string(globalMouse.x))
136 .append(",\"globalY\":")
137 .append(std::to_string(globalMouse.y))
138 .append(",\"globalZ\":")
139 .append(std::to_string(globalMouse.z))
140 .append(",\"localX\":")
141 .append(std::to_string(globalMouse.x))
142 .append(",\"localY\":")
143 .append(std::to_string(globalMouse.y))
144 .append(",\"localZ\":")
145 .append(std::to_string(globalMouse.z))
146 .append(",\"deltaX\":")
147 .append(std::to_string(globalMouse.deltaX))
148 .append(",\"deltaY\":")
149 .append(std::to_string(globalMouse.deltaY))
150 .append(",\"deltaZ\":")
151 .append(std::to_string(globalMouse.deltaZ))
152 .append(",\"scrollX\":")
153 .append(std::to_string(globalMouse.scrollX))
154 .append(",\"scrollY\":")
155 .append(std::to_string(globalMouse.scrollY))
156 .append(",\"scrollZ\":")
157 .append(std::to_string(globalMouse.scrollZ))
158 .append(",\"action\":")
159 .append(std::to_string(static_cast<int32_t>(globalMouse.action)))
160 .append(",\"button\":")
161 .append(std::to_string(static_cast<int32_t>(globalMouse.button)))
162 .append(",\"pressedButtons\":")
163 .append(std::to_string(globalMouse.pressedButtons));
164 }
165 eventParam.append("}}");
166 }
167
SwipeInfoToString(const BaseEventInfo & info,std::string & eventParam)168 void SwipeInfoToString(const BaseEventInfo& info, std::string& eventParam)
169 {
170 const auto swipeInfo = TypeInfoHelper::DynamicCast<SwipeEventInfo>(&info);
171 if (swipeInfo != nullptr) {
172 eventParam = swipeInfo->ToJsonParamInfo();
173 }
174 }
175
176 } // namespace
177
HandleAsyncEvent(const OHOS::Ace::EventMarker & eventMarker)178 void CJEventHandler::HandleAsyncEvent(const OHOS::Ace::EventMarker& eventMarker)
179 {
180 auto frontend = frontend_.Upgrade();
181 CHECK_NULL_VOID(frontend);
182
183 LOGI("HandleAsyncEvent pageId: %{private}d, eventId: %{private}s, eventType: %{private}s",
184 eventMarker.GetData().pageId, eventMarker.GetData().eventId.c_str(), eventMarker.GetData().eventType.c_str());
185
186 std::string param = eventMarker.GetData().GetEventParam();
187 frontend->GetTaskExecutor()->PostTask([eventMarker] {
188 eventMarker.CallUiFunction();
189 }, TaskExecutor::TaskType::UI, "CJHandleAsyncEvent");
190
191 AccessibilityEvent accessibilityEvent;
192 accessibilityEvent.nodeId = StringUtils::StringToInt(eventMarker.GetData().eventId);
193 accessibilityEvent.eventType = eventMarker.GetData().eventType;
194 frontend->GetAccessibilityManager()->SendAccessibilityAsyncEvent(accessibilityEvent);
195 }
196
HandleAsyncEvent(const OHOS::Ace::EventMarker & eventMarker,const BaseEventInfo & info)197 void CJEventHandler::HandleAsyncEvent(const OHOS::Ace::EventMarker& eventMarker, const BaseEventInfo& info)
198 {
199 auto frontend = frontend_.Upgrade();
200 CHECK_NULL_VOID(frontend);
201
202 std::string eventParam;
203 if (eventMarker.GetData().eventType.find("touch") != std::string::npos) {
204 TouchInfoToString(info, eventParam);
205 } else if (eventMarker.GetData().eventType.find("mouse") != std::string::npos) {
206 MouseInfoToString(info, eventParam);
207 } else if (eventMarker.GetData().eventType == "swipe") {
208 SwipeInfoToString(info, eventParam);
209 }
210
211 LOGD("HandleAsyncEvent pageId: %{public}d, eventId: %{public}s, eventType: %{public}s",
212 eventMarker.GetData().pageId, eventMarker.GetData().eventId.c_str(), eventMarker.GetData().eventType.c_str());
213 std::string param = eventMarker.GetData().GetEventParam();
214 if (eventParam.empty()) {
215 param.append("null");
216 } else {
217 param.append(eventParam);
218 }
219 frontend->GetTaskExecutor()->PostTask([eventMarker, info = CopyEventInfo(info)] {
220 eventMarker.CallUiArgFunction(info.get());
221 }, TaskExecutor::TaskType::UI, "CJHandleAsyncEvent");
222
223 AccessibilityEvent accessibilityEvent;
224 accessibilityEvent.nodeId = StringUtils::StringToInt(eventMarker.GetData().eventId);
225 accessibilityEvent.eventType = eventMarker.GetData().eventType;
226 frontend->GetAccessibilityManager()->SendAccessibilityAsyncEvent(accessibilityEvent);
227 }
228
HandleAsyncEvent(const EventMarker & eventMarker,const std::shared_ptr<BaseEventInfo> & info)229 void CJEventHandler::HandleAsyncEvent(const EventMarker& eventMarker, const std::shared_ptr<BaseEventInfo>& info)
230 {
231 auto frontend = frontend_.Upgrade();
232 CHECK_NULL_VOID(frontend);
233
234 frontend->GetTaskExecutor()->PostTask([eventMarker, info] {
235 eventMarker.CallUiArgFunction(info.get());
236 }, TaskExecutor::TaskType::UI, "CJHandleAsyncEvent");
237 }
238
HandleAsyncEvent(const EventMarker & eventMarker,int32_t param)239 void CJEventHandler::HandleAsyncEvent(const EventMarker& eventMarker, int32_t param)
240 {
241 auto frontend = frontend_.Upgrade();
242 CHECK_NULL_VOID(frontend);
243
244 AccessibilityEvent accessibilityEvent;
245 accessibilityEvent.nodeId = StringUtils::StringToInt(eventMarker.GetData().eventId);
246 accessibilityEvent.eventType = eventMarker.GetData().eventType;
247 frontend->GetAccessibilityManager()->SendAccessibilityAsyncEvent(accessibilityEvent);
248 }
249
HandleAsyncEvent(const EventMarker & eventMarker,const KeyEvent & info)250 void CJEventHandler::HandleAsyncEvent(const EventMarker& eventMarker, const KeyEvent& info)
251 {
252 auto frontend = frontend_.Upgrade();
253 CHECK_NULL_VOID(frontend);
254
255 AccessibilityEvent accessibilityEvent;
256 accessibilityEvent.nodeId = StringUtils::StringToInt(eventMarker.GetData().eventId);
257 accessibilityEvent.eventType = eventMarker.GetData().eventType;
258 frontend->GetAccessibilityManager()->SendAccessibilityAsyncEvent(accessibilityEvent);
259 }
260
HandleAsyncEvent(const EventMarker & eventMarker,const std::string & param)261 void CJEventHandler::HandleAsyncEvent(const EventMarker& eventMarker, const std::string& param)
262 {
263 LOGD("HandleAsyncEvent pageId: %{public}d, eventId: %{public}s", eventMarker.GetData().pageId,
264 eventMarker.GetData().eventId.c_str());
265 auto frontend = frontend_.Upgrade();
266 CHECK_NULL_VOID(frontend);
267
268 std::string fixParam(param);
269 std::string::size_type startPos = param.find_first_of("{");
270 std::string::size_type endPos = param.find_last_of("}");
271 if (startPos != std::string::npos && endPos != std::string::npos && startPos < endPos) {
272 fixParam = fixParam.substr(startPos, endPos - startPos + 1);
273 }
274
275 frontend->GetTaskExecutor()->PostTask([eventMarker, fixParam] {
276 eventMarker.CallUiStrFunction(fixParam);
277 }, TaskExecutor::TaskType::UI, "CJHandleAsyncEvent");
278
279 AccessibilityEvent accessibilityEvent;
280 accessibilityEvent.nodeId = StringUtils::StringToInt(eventMarker.GetData().eventId);
281 accessibilityEvent.eventType = eventMarker.GetData().eventType;
282 frontend->GetAccessibilityManager()->SendAccessibilityAsyncEvent(accessibilityEvent);
283 }
284
HandleSyncEvent(const EventMarker & eventMarker,const KeyEvent & info,bool & result)285 void CJEventHandler::HandleSyncEvent(const EventMarker& eventMarker, const KeyEvent& info, bool& result)
286 {
287 LOGD("HandleSyncEvent pageId: %{public}d, eventId: %{public}s, eventType: %{public}s", eventMarker.GetData().pageId,
288 eventMarker.GetData().eventId.c_str(), eventMarker.GetData().eventType.c_str());
289 auto frontend = frontend_.Upgrade();
290 CHECK_NULL_VOID(frontend);
291
292 std::string param = std::string("\"")
293 .append(eventMarker.GetData().eventType)
294 .append("\",{\"code\":")
295 .append(std::to_string(static_cast<int32_t>(info.code)))
296 .append(",\"action\":")
297 .append(std::to_string(static_cast<int32_t>(info.action)))
298 .append(",\"repeatCount\":")
299 .append(std::to_string(static_cast<int32_t>(info.repeatTime)))
300 .append(",\"timestamp\":")
301 .append(std::to_string(info.timeStamp.time_since_epoch().count()))
302 .append(",\"key\":\"")
303 .append(info.key)
304 .append("\"},");
305
306 result = false;
307
308 AccessibilityEvent accessibilityEvent;
309 accessibilityEvent.nodeId = StringUtils::StringToInt(eventMarker.GetData().eventId);
310 accessibilityEvent.eventType = std::to_string(static_cast<int32_t>(info.code));
311 frontend->GetAccessibilityManager()->SendAccessibilityAsyncEvent(accessibilityEvent);
312 }
313
HandleSyncEvent(const EventMarker & eventMarker,bool & result)314 void CJEventHandler::HandleSyncEvent(const EventMarker& eventMarker, bool& result)
315 {
316 auto frontend = frontend_.Upgrade();
317 CHECK_NULL_VOID(frontend);
318
319 result = false;
320
321 AccessibilityEvent accessibilityEvent;
322 accessibilityEvent.nodeId = StringUtils::StringToInt(eventMarker.GetData().eventId);
323 accessibilityEvent.eventType = eventMarker.GetData().eventType;
324 frontend->GetAccessibilityManager()->SendAccessibilityAsyncEvent(accessibilityEvent);
325 }
326
HandleSyncEvent(const EventMarker & eventMarker,const std::shared_ptr<BaseEventInfo> & info)327 void CJEventHandler::HandleSyncEvent(
328 const EventMarker& eventMarker, const std::shared_ptr<BaseEventInfo>& info)
329 {
330 auto frontend = frontend_.Upgrade();
331 CHECK_NULL_VOID(frontend);
332
333 frontend->GetTaskExecutor()->PostTask([eventMarker, info] {
334 eventMarker.CallUiArgFunction(info.get());
335 }, TaskExecutor::TaskType::UI, "CJHandleAsyncEvent");
336 }
337
HandleSyncEvent(const EventMarker & eventMarker,const BaseEventInfo & info,bool & result)338 void CJEventHandler::HandleSyncEvent(const EventMarker& eventMarker, const BaseEventInfo& info, bool& result)
339 {
340 auto frontend = frontend_.Upgrade();
341 CHECK_NULL_VOID(frontend);
342
343 AccessibilityEvent accessibilityEvent;
344 accessibilityEvent.nodeId = StringUtils::StringToInt(eventMarker.GetData().eventId);
345 accessibilityEvent.eventType = eventMarker.GetData().eventType;
346 frontend->GetAccessibilityManager()->SendAccessibilityAsyncEvent(accessibilityEvent);
347 }
348
HandleSyncEvent(const EventMarker & eventMarker,const std::string & param,std::string & result)349 void CJEventHandler::HandleSyncEvent(
350 const EventMarker& eventMarker, const std::string& param, std::string& result)
351 {
352 auto frontend = frontend_.Upgrade();
353 CHECK_NULL_VOID(frontend);
354
355 AccessibilityEvent accessibilityEvent;
356 accessibilityEvent.nodeId = StringUtils::StringToInt(eventMarker.GetData().eventId);
357 accessibilityEvent.eventType = eventMarker.GetData().eventType;
358 frontend->GetAccessibilityManager()->SendAccessibilityAsyncEvent(accessibilityEvent);
359 }
360
HandleSyncEvent(const EventMarker & eventMarker,const std::string & componentId,const int32_t nodeId,const bool isDestroy)361 void CJEventHandler::HandleSyncEvent(
362 const EventMarker& eventMarker, const std::string& componentId, const int32_t nodeId, const bool isDestroy)
363 {
364 }
365
366 }