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