1 /*
2 * Copyright (c) 2022-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/web/web_pattern.h"
17
18 #include <securec.h>
19 #include <algorithm>
20 #include <cmath>
21 #include <filesystem>
22 #include <iomanip>
23 #include <iostream>
24 #include <string>
25 #include <sstream>
26 #include <string_ex.h>
27 #include <unordered_map>
28 #include <vector>
29
30 #include "display_manager.h"
31 #include "file_uri.h"
32 #include "image_source.h"
33 #include "input_method_controller.h"
34 #include "parameters.h"
35
36 #include "interfaces/inner_api/ui_session/ui_session_manager.h"
37 #include "auto_fill_type.h"
38 #include "page_node_info.h"
39
40 #include "adapter/ohos/capability/html/span_to_html.h"
41 #include "base/geometry/ng/offset_t.h"
42 #include "base/geometry/rect.h"
43 #include "base/image/file_uri_helper.h"
44 #include "base/log/dump_log.h"
45 #include "base/utils/utils.h"
46 #include "base/mousestyle/mouse_style.h"
47 #include "base/utils/date_util.h"
48 #include "base/utils/linear_map.h"
49 #include "base/utils/time_util.h"
50 #include "base/utils/utils.h"
51 #include "base/web/webview/arkweb_utils/arkweb_utils.h"
52 #include "bridge/common/utils/engine_helper.h"
53 #include "core/common/ace_engine_ext.h"
54 #include "core/common/ai/image_analyzer_manager.h"
55 #include "core/common/container.h"
56 #include "core/common/ime/input_method_manager.h"
57 #include "core/common/recorder/event_definition.h"
58 #include "core/common/recorder/event_recorder.h"
59 #include "core/common/recorder/inspector_tree_collector.h"
60 #include "core/common/stylus/stylus_detector_mgr.h"
61 #include "core/common/udmf/udmf_client.h"
62 #include "core/common/udmf/unified_data.h"
63 #include "core/common/vibrator/vibrator_utils.h"
64 #include "core/components/dialog/dialog_theme.h"
65 #include "core/components/picker/picker_data.h"
66 #include "core/components/text_overlay/text_overlay_theme.h"
67 #include "core/components/theme/shadow_theme.h"
68 #include "core/components/web/resource/web_delegate.h"
69 #include "core/components/web/web_property.h"
70 #include "core/components_ng/base/view_stack_processor.h"
71 #include "core/components_ng/pattern/dialog/dialog_pattern.h"
72 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
73 #include "core/components_ng/pattern/list/list_pattern.h"
74 #include "core/components_ng/pattern/menu/menu_view.h"
75 #include "core/components_ng/pattern/menu/wrapper/menu_wrapper_pattern.h"
76 #include "core/components_ng/pattern/overlay/overlay_manager.h"
77 #include "core/components_ng/pattern/refresh/refresh_pattern.h"
78 #include "core/components_ng/pattern/select_overlay/select_overlay_pattern.h"
79 #include "core/components_ng/pattern/swiper/swiper_pattern.h"
80 #include "core/components_ng/pattern/text/text_pattern.h"
81 #include "core/components_ng/pattern/text_field/text_field_manager.h"
82 #include "core/components_ng/pattern/web/web_accessibility_child_tree_callback.h"
83 #include "core/components_ng/pattern/web/web_event_hub.h"
84 #include "core/components_ng/pattern/web/view_data_common.h"
85 #include "core/components_ng/pattern/web/transitional_node_info.h"
86 #include "core/event/key_event.h"
87 #include "core/event/touch_event.h"
88 #include "core/event/event_info_convertor.h"
89 #include "core/pipeline_ng/pipeline_context.h"
90 #include "frameworks/base/utils/system_properties.h"
91 #include "frameworks/core/components_ng/base/ui_node.h"
92 #include "oh_window_pip.h"
93 #include "oh_window_comm.h"
94 #include "web_accessibility_session_adapter.h"
95 #include "web_pattern.h"
96 #include "nweb_handler.h"
97
98 namespace OHOS::Ace::NG {
99 namespace {
100 const std::string IMAGE_POINTER_CONTEXT_MENU_PATH = "etc/webview/ohos_nweb/context-menu.svg";
101 const std::string IMAGE_POINTER_ALIAS_PATH = "etc/webview/ohos_nweb/alias.svg";
102 const std::string AUTO_FILL_VIEW_DATA_PAGE_URL = "autofill_viewdata_origin_pageurl";
103 const std::string AUTO_FILL_VIEW_DATA_OTHER_ACCOUNT = "autofill_viewdata_other_account";
104 const std::string AUTO_FILL_START_POPUP_WINDOW = "persist.sys.abilityms.autofill.is_passwd_popup_window";
105 const std::string WEB_INFO_PC = "8";
106 const std::string WEB_INFO_TABLET = "4";
107 const std::string WEB_INFO_PHONE = "2";
108 const std::string WEB_INFO_DEFAULT = "1";
109 const std::string WEB_SNAPSHOT_PATH_PREFIX = "/data/storage/el2/base/cache/web/snapshot/web_frame_";
110 const std::string WEB_SNAPSHOT_PATH_SUFFIX = ".png";
111 constexpr int32_t UPDATE_WEB_LAYOUT_DELAY_TIME = 20;
112 constexpr int32_t AUTOFILL_DELAY_TIME = 200;
113 constexpr int32_t IMAGE_POINTER_CUSTOM_CHANNEL = 4;
114 constexpr int32_t TOUCH_EVENT_MAX_SIZE = 5;
115 constexpr int32_t MOUSE_EVENT_MAX_SIZE = 10;
116 constexpr int32_t KEYEVENT_MAX_NUM = 1000;
117 constexpr int32_t MAXIMUM_ROTATION_DELAY_TIME = 800;
118 constexpr int32_t RESERVED_DEVICEID1 = 0xAAAAAAFF;
119 constexpr int32_t RESERVED_DEVICEID2 = 0xAAAAAAFE;
120 const LinearEnumMapNode<OHOS::NWeb::CursorType, MouseFormat> g_cursorTypeMap[] = {
121 { OHOS::NWeb::CursorType::CT_CROSS, MouseFormat::CROSS },
122 { OHOS::NWeb::CursorType::CT_HAND, MouseFormat::HAND_POINTING },
123 { OHOS::NWeb::CursorType::CT_IBEAM, MouseFormat::TEXT_CURSOR },
124 { OHOS::NWeb::CursorType::CT_WAIT, MouseFormat::LOADING },
125 { OHOS::NWeb::CursorType::CT_HELP, MouseFormat::HELP },
126 { OHOS::NWeb::CursorType::CT_EASTRESIZE, MouseFormat::WEST_EAST },
127 { OHOS::NWeb::CursorType::CT_NORTHRESIZE, MouseFormat::NORTH_SOUTH },
128 { OHOS::NWeb::CursorType::CT_NORTHEASTRESIZE, MouseFormat::NORTH_EAST_SOUTH_WEST },
129 { OHOS::NWeb::CursorType::CT_NORTHWESTRESIZE, MouseFormat::NORTH_WEST_SOUTH_EAST },
130 { OHOS::NWeb::CursorType::CT_SOUTHRESIZE, MouseFormat::NORTH_SOUTH },
131 { OHOS::NWeb::CursorType::CT_SOUTHEASTRESIZE, MouseFormat::NORTH_WEST_SOUTH_EAST },
132 { OHOS::NWeb::CursorType::CT_SOUTHWESTRESIZE, MouseFormat::NORTH_EAST_SOUTH_WEST },
133 { OHOS::NWeb::CursorType::CT_WESTRESIZE, MouseFormat::WEST_EAST },
134 { OHOS::NWeb::CursorType::CT_NORTHSOUTHRESIZE, MouseFormat::NORTH_SOUTH },
135 { OHOS::NWeb::CursorType::CT_EASTWESTRESIZE, MouseFormat::WEST_EAST },
136 { OHOS::NWeb::CursorType::CT_NORTHEASTSOUTHWESTRESIZE, MouseFormat::NORTH_EAST_SOUTH_WEST },
137 { OHOS::NWeb::CursorType::CT_NORTHWESTSOUTHEASTRESIZE, MouseFormat::NORTH_WEST_SOUTH_EAST },
138 { OHOS::NWeb::CursorType::CT_COLUMNRESIZE, MouseFormat::RESIZE_LEFT_RIGHT },
139 { OHOS::NWeb::CursorType::CT_ROWRESIZE, MouseFormat::RESIZE_UP_DOWN },
140 { OHOS::NWeb::CursorType::CT_MIDDLEPANNING, MouseFormat::MIDDLE_BTN_NORTH_SOUTH_WEST_EAST },
141 { OHOS::NWeb::CursorType::CT_EASTPANNING, MouseFormat::MIDDLE_BTN_EAST },
142 { OHOS::NWeb::CursorType::CT_NORTHPANNING, MouseFormat::MIDDLE_BTN_NORTH },
143 { OHOS::NWeb::CursorType::CT_NORTHEASTPANNING, MouseFormat::MIDDLE_BTN_NORTH_EAST },
144 { OHOS::NWeb::CursorType::CT_NORTHWESTPANNING, MouseFormat::MIDDLE_BTN_NORTH_WEST },
145 { OHOS::NWeb::CursorType::CT_SOUTHPANNING, MouseFormat::MIDDLE_BTN_SOUTH },
146 { OHOS::NWeb::CursorType::CT_SOUTHEASTPANNING, MouseFormat::MIDDLE_BTN_SOUTH_EAST },
147 { OHOS::NWeb::CursorType::CT_SOUTHWESTPANNING, MouseFormat::MIDDLE_BTN_SOUTH_WEST },
148 { OHOS::NWeb::CursorType::CT_WESTPANNING, MouseFormat::MIDDLE_BTN_WEST },
149 { OHOS::NWeb::CursorType::CT_MOVE, MouseFormat::CURSOR_MOVE },
150 { OHOS::NWeb::CursorType::CT_VERTICALTEXT, MouseFormat::HORIZONTAL_TEXT_CURSOR },
151 { OHOS::NWeb::CursorType::CT_CELL, MouseFormat::CURSOR_CROSS },
152 { OHOS::NWeb::CursorType::CT_PROGRESS, MouseFormat::RUNNING },
153 { OHOS::NWeb::CursorType::CT_NODROP, MouseFormat::CURSOR_FORBID },
154 { OHOS::NWeb::CursorType::CT_COPY, MouseFormat::CURSOR_COPY },
155 { OHOS::NWeb::CursorType::CT_NONE, MouseFormat::CURSOR_NONE },
156 { OHOS::NWeb::CursorType::CT_NOTALLOWED, MouseFormat::CURSOR_FORBID },
157 { OHOS::NWeb::CursorType::CT_ZOOMIN, MouseFormat::ZOOM_IN },
158 { OHOS::NWeb::CursorType::CT_ZOOMOUT, MouseFormat::ZOOM_OUT },
159 { OHOS::NWeb::CursorType::CT_GRAB, MouseFormat::HAND_OPEN },
160 { OHOS::NWeb::CursorType::CT_GRABBING, MouseFormat::HAND_GRABBING },
161 { OHOS::NWeb::CursorType::CT_MIDDLE_PANNING_VERTICAL, MouseFormat::MIDDLE_BTN_NORTH_SOUTH },
162 { OHOS::NWeb::CursorType::CT_MIDDLE_PANNING_HORIZONTAL, MouseFormat::MIDDLE_BTN_NORTH_SOUTH_WEST_EAST },
163 };
164
165 std::unordered_map<KeyCode, KeyCode> g_numPadFunctionMap = {
166 { KeyCode::KEY_NUMPAD_0, KeyCode::KEY_INSERT },
167 { KeyCode::KEY_NUMPAD_1, KeyCode::KEY_MOVE_END },
168 { KeyCode::KEY_NUMPAD_2, KeyCode::KEY_DPAD_DOWN },
169 { KeyCode::KEY_NUMPAD_3, KeyCode::KEY_PAGE_DOWN },
170 { KeyCode::KEY_NUMPAD_4, KeyCode::KEY_DPAD_LEFT },
171 { KeyCode::KEY_NUMPAD_5, KeyCode::KEY_CLEAR },
172 { KeyCode::KEY_NUMPAD_6, KeyCode::KEY_DPAD_RIGHT },
173 { KeyCode::KEY_NUMPAD_7, KeyCode::KEY_MOVE_HOME },
174 { KeyCode::KEY_NUMPAD_8, KeyCode::KEY_DPAD_UP },
175 { KeyCode::KEY_NUMPAD_9, KeyCode::KEY_PAGE_UP },
176 { KeyCode::KEY_NUMPAD_DIVIDE, KeyCode::KEY_NUMPAD_DIVIDE },
177 { KeyCode::KEY_NUMPAD_MULTIPLY, KeyCode::KEY_NUMPAD_MULTIPLY },
178 { KeyCode::KEY_NUMPAD_SUBTRACT, KeyCode::KEY_NUMPAD_SUBTRACT },
179 { KeyCode::KEY_NUMPAD_ADD, KeyCode::KEY_NUMPAD_ADD },
180 { KeyCode::KEY_NUMPAD_DOT, KeyCode::KEY_FORWARD_DEL },
181 { KeyCode::KEY_NUMPAD_ENTER, KeyCode::KEY_NUMPAD_ENTER }
182 };
183
184 constexpr Dimension OPTION_MARGIN = 8.0_vp;
185 constexpr Dimension CALIBERATE_X = 4.0_vp;
186 constexpr Color SELECTED_OPTION_FONT_COLOR = Color(0xff0a59f7);
187 constexpr Color SELECTED_OPTION_BACKGROUND_COLOR = Color(0x19254FF7);
188
189 constexpr int32_t HALF = 2;
190 constexpr int32_t AI_TIMEOUT_LIMIT = 200;
191 constexpr int32_t CHECK_PRE_SIZE = 5;
192 constexpr int32_t ADJUST_RATIO = 10;
193 constexpr int32_t DRAG_RESIZE_DELAY_TIME = 100;
194 constexpr int32_t DRAG_RESIZE_NO_MOVE_CHECK_TIME = 200;
195
196 struct TranslateTextExtraData {
197 bool needTranslate = false;
198 std::string registerObjectName = "";
199 std::string registerFunctionName = "";
200 std::string translateScript = "";
201 std::string initScript = "";
202 };
203 TranslateTextExtraData g_translateTextData;
204 uint32_t g_currentControllerId = 0;
205 bool g_currentControllerIdStop = false;
206 enum PictureInPictureState {
207 PIP_STATE_ENTER = 0,
208 PIP_STATE_EXIT,
209 PIP_STATE_PLAY,
210 PIP_STATE_PAUSE,
211 PIP_STATE_FAST_FORWARD,
212 PIP_STATE_FAST_BACKWARD,
213 PIP_STATE_RESTORE,
214 PIP_STATE_HLS_ENTER,
215 PIP_STATE_HLS_EXIT,
216 PIP_STATE_RESIZE,
217 PIP_STATE_NONE,
218 };
219
220 struct PipData {
221 int delegateId = -1;
222 int childId = -1;
223 int frameRoutingId = -1;
224 int preStatus = -1;
225 RefPtr<WebPattern> pipWebPattern = nullptr;
226 };
227
228 std::unordered_map<uint32_t, PipData> pipCallbackMap_;
229 std::mutex pipCallbackMapMutex_;
230
ParseDateTimeJson(const std::string & timeJson,NWeb::DateTime & result)231 bool ParseDateTimeJson(const std::string& timeJson, NWeb::DateTime& result)
232 {
233 auto sourceJson = JsonUtil::ParseJsonString(timeJson);
234 if (!sourceJson || sourceJson->IsNull()) {
235 return false;
236 }
237
238 auto year = sourceJson->GetValue("year");
239 if (year && year->IsNumber()) {
240 result.year = year->GetInt();
241 }
242 auto month = sourceJson->GetValue("month");
243 if (month && month->IsNumber()) {
244 result.month = month->GetInt();
245 }
246 auto day = sourceJson->GetValue("day");
247 if (day && day->IsNumber()) {
248 result.day = day->GetInt();
249 }
250 auto hour = sourceJson->GetValue("hour");
251 if (hour && hour->IsNumber()) {
252 result.hour = hour->GetInt();
253 }
254 auto minute = sourceJson->GetValue("minute");
255 if (minute && minute->IsNumber()) {
256 result.minute = minute->GetInt();
257 }
258 return true;
259 }
260
ParseTextJsonValue(const std::string & textJson)261 std::string ParseTextJsonValue(const std::string& textJson)
262 {
263 auto sourceJson = JsonUtil::ParseJsonString(textJson);
264 if (!sourceJson || sourceJson->IsNull()) {
265 return "";
266 }
267 auto value = sourceJson->GetValue("value");
268 if (value && value->IsString()) {
269 return value->GetString();
270 }
271 return "";
272 }
273
274 const std::string NWEB_AUTOFILL_TYPE_OFF = "off";
275 const std::map<std::string, AceAutoFillType> NWEB_AUTOFILL_TYPE_TO_ACE = {
276 {OHOS::NWeb::NWEB_AUTOFILL_STREET_ADDRESS, AceAutoFillType::ACE_FULL_STREET_ADDRESS},
277 {OHOS::NWeb::NWEB_AUTOFILL_ADDRESS_LEVEL_3, AceAutoFillType::ACE_DISTRICT_ADDRESS},
278 {OHOS::NWeb::NWEB_AUTOFILL_ADDRESS_LEVEL_2, AceAutoFillType::ACE_CITY_ADDRESS},
279 {OHOS::NWeb::NWEB_AUTOFILL_ADDRESS_LEVEL_1, AceAutoFillType::ACE_PROVINCE_ADDRESS},
280 {OHOS::NWeb::NWEB_AUTOFILL_COUNTRY, AceAutoFillType::ACE_COUNTRY_ADDRESS},
281 {OHOS::NWeb::NWEB_AUTOFILL_NAME, AceAutoFillType::ACE_PERSON_FULL_NAME},
282 {OHOS::NWeb::NWEB_AUTOFILL_FAMILY_NAME, AceAutoFillType::ACE_PERSON_LAST_NAME},
283 {OHOS::NWeb::NWEB_AUTOFILL_GIVEN_NAME, AceAutoFillType::ACE_PERSON_FIRST_NAME},
284 {OHOS::NWeb::NWEB_AUTOFILL_TEL_NATIONAL, AceAutoFillType::ACE_PHONE_NUMBER},
285 {OHOS::NWeb::NWEB_AUTOFILL_TEL, AceAutoFillType::ACE_FULL_PHONE_NUMBER},
286 {OHOS::NWeb::NWEB_AUTOFILL_TEL_COUNTRY_CODE, AceAutoFillType::ACE_PHONE_COUNTRY_CODE},
287 {OHOS::NWeb::NWEB_AUTOFILL_EMAIL, AceAutoFillType::ACE_EMAIL_ADDRESS},
288 {OHOS::NWeb::NWEB_AUTOFILL_CC_NUMBER, AceAutoFillType::ACE_BANK_CARD_NUMBER},
289 {OHOS::NWeb::NWEB_AUTOFILL_ID_CARD_NUMBER, AceAutoFillType::ACE_ID_CARD_NUMBER},
290 {OHOS::NWeb::NWEB_AUTOFILL_DETAIL_INFO_WITHOUT_STREET, AceAutoFillType::ACE_DETAIL_INFO_WITHOUT_STREET},
291 {OHOS::NWeb::NWEB_AUTOFILL_FORMAT_ADDRESS, AceAutoFillType::ACE_FORMAT_ADDRESS},
292 {OHOS::NWeb::NWEB_AUTOFILL_NICKNAME, AceAutoFillType::ACE_NICKNAME},
293 {OHOS::NWeb::NWEB_AUTOFILL_USERNAME, AceAutoFillType::ACE_USER_NAME},
294 {OHOS::NWeb::NWEB_AUTOFILL_PASSWORD, AceAutoFillType::ACE_PASSWORD},
295 {OHOS::NWeb::NWEB_AUTOFILL_NEW_PASSWORD, AceAutoFillType::ACE_NEW_PASSWORD},
296 {OHOS::NWeb::NWEB_AUTOFILL_PASSPORT_NUMBER, AceAutoFillType::ACE_PASSPORT_NUMBER},
297 {OHOS::NWeb::NWEB_AUTOFILL_VALIDITY, AceAutoFillType::ACE_VALIDITY},
298 {OHOS::NWeb::NWEB_AUTOFILL_ISSUE_AT, AceAutoFillType::ACE_ISSUE_AT},
299 {OHOS::NWeb::NWEB_AUTOFILL_ORGANIZATION, AceAutoFillType::ACE_ORGANIZATION},
300 {OHOS::NWeb::NWEB_AUTOFILL_TAX_ID, AceAutoFillType::ACE_TAX_ID},
301 {OHOS::NWeb::NWEB_AUTOFILL_ADDRESS_CITY_AND_STATE, AceAutoFillType::ACE_ADDRESS_CITY_AND_STATE},
302 {OHOS::NWeb::NWEB_AUTOFILL_FLIGHT_NUMBER, AceAutoFillType::ACE_FLIGHT_NUMBER},
303 {OHOS::NWeb::NWEB_AUTOFILL_LICENSE_NUMBER, AceAutoFillType::ACE_LICENSE_NUMBER},
304 {OHOS::NWeb::NWEB_AUTOFILL_LICENSE_FILE_NUMBER, AceAutoFillType::ACE_LICENSE_FILE_NUMBER},
305 {OHOS::NWeb::NWEB_AUTOFILL_LICENSE_PLATE, AceAutoFillType::ACE_LICENSE_PLATE},
306 {OHOS::NWeb::NWEB_AUTOFILL_ENGINE_NUMBER, AceAutoFillType::ACE_ENGINE_NUMBER},
307 {OHOS::NWeb::NWEB_AUTOFILL_LICENSE_CHASSIS_NUMBER, AceAutoFillType::ACE_LICENSE_CHASSIS_NUMBER},
308 };
309
310 const std::map<AceAutoFillType, std::string> ACE_AUTOFILL_TYPE_TO_NWEB = {
311 {AceAutoFillType::ACE_FULL_STREET_ADDRESS, OHOS::NWeb::NWEB_AUTOFILL_STREET_ADDRESS},
312 {AceAutoFillType::ACE_DISTRICT_ADDRESS, OHOS::NWeb::NWEB_AUTOFILL_ADDRESS_LEVEL_3},
313 {AceAutoFillType::ACE_CITY_ADDRESS, OHOS::NWeb::NWEB_AUTOFILL_ADDRESS_LEVEL_2},
314 {AceAutoFillType::ACE_PROVINCE_ADDRESS, OHOS::NWeb::NWEB_AUTOFILL_ADDRESS_LEVEL_1},
315 {AceAutoFillType::ACE_COUNTRY_ADDRESS, OHOS::NWeb::NWEB_AUTOFILL_COUNTRY},
316 {AceAutoFillType::ACE_PERSON_FULL_NAME, OHOS::NWeb::NWEB_AUTOFILL_NAME},
317 {AceAutoFillType::ACE_PERSON_LAST_NAME, OHOS::NWeb::NWEB_AUTOFILL_FAMILY_NAME},
318 {AceAutoFillType::ACE_PERSON_FIRST_NAME, OHOS::NWeb::NWEB_AUTOFILL_GIVEN_NAME},
319 {AceAutoFillType::ACE_PHONE_NUMBER, OHOS::NWeb::NWEB_AUTOFILL_TEL_NATIONAL},
320 {AceAutoFillType::ACE_FULL_PHONE_NUMBER, OHOS::NWeb::NWEB_AUTOFILL_TEL},
321 {AceAutoFillType::ACE_PHONE_COUNTRY_CODE, OHOS::NWeb::NWEB_AUTOFILL_TEL_COUNTRY_CODE},
322 {AceAutoFillType::ACE_EMAIL_ADDRESS, OHOS::NWeb::NWEB_AUTOFILL_EMAIL},
323 {AceAutoFillType::ACE_BANK_CARD_NUMBER, OHOS::NWeb::NWEB_AUTOFILL_CC_NUMBER},
324 {AceAutoFillType::ACE_ID_CARD_NUMBER, OHOS::NWeb::NWEB_AUTOFILL_ID_CARD_NUMBER},
325 {AceAutoFillType::ACE_DETAIL_INFO_WITHOUT_STREET, OHOS::NWeb::NWEB_AUTOFILL_DETAIL_INFO_WITHOUT_STREET},
326 {AceAutoFillType::ACE_FORMAT_ADDRESS, OHOS::NWeb::NWEB_AUTOFILL_FORMAT_ADDRESS},
327 {AceAutoFillType::ACE_NICKNAME, OHOS::NWeb::NWEB_AUTOFILL_NICKNAME},
328 {AceAutoFillType::ACE_USER_NAME, OHOS::NWeb::NWEB_AUTOFILL_USERNAME},
329 {AceAutoFillType::ACE_PASSWORD, OHOS::NWeb::NWEB_AUTOFILL_PASSWORD},
330 {AceAutoFillType::ACE_NEW_PASSWORD, OHOS::NWeb::NWEB_AUTOFILL_NEW_PASSWORD},
331 {AceAutoFillType::ACE_PASSPORT_NUMBER, OHOS::NWeb::NWEB_AUTOFILL_PASSPORT_NUMBER},
332 {AceAutoFillType::ACE_VALIDITY, OHOS::NWeb::NWEB_AUTOFILL_VALIDITY},
333 {AceAutoFillType::ACE_ISSUE_AT, OHOS::NWeb::NWEB_AUTOFILL_ISSUE_AT},
334 {AceAutoFillType::ACE_ORGANIZATION, OHOS::NWeb::NWEB_AUTOFILL_ORGANIZATION},
335 {AceAutoFillType::ACE_TAX_ID, OHOS::NWeb::NWEB_AUTOFILL_TAX_ID},
336 {AceAutoFillType::ACE_ADDRESS_CITY_AND_STATE, OHOS::NWeb::NWEB_AUTOFILL_ADDRESS_CITY_AND_STATE},
337 {AceAutoFillType::ACE_FLIGHT_NUMBER, OHOS::NWeb::NWEB_AUTOFILL_FLIGHT_NUMBER},
338 {AceAutoFillType::ACE_LICENSE_NUMBER, OHOS::NWeb::NWEB_AUTOFILL_LICENSE_NUMBER},
339 {AceAutoFillType::ACE_LICENSE_FILE_NUMBER, OHOS::NWeb::NWEB_AUTOFILL_LICENSE_FILE_NUMBER},
340 {AceAutoFillType::ACE_LICENSE_PLATE, OHOS::NWeb::NWEB_AUTOFILL_LICENSE_PLATE},
341 {AceAutoFillType::ACE_ENGINE_NUMBER, OHOS::NWeb::NWEB_AUTOFILL_ENGINE_NUMBER},
342 {AceAutoFillType::ACE_LICENSE_CHASSIS_NUMBER, OHOS::NWeb::NWEB_AUTOFILL_LICENSE_CHASSIS_NUMBER},
343 };
344
345 const std::map<std::string, OHOS::NWeb::NWebAutofillEvent> NWEB_AUTOFILL_EVENTS = {
346 {OHOS::NWeb::NWEB_AUTOFILL_EVENT_SAVE, OHOS::NWeb::NWebAutofillEvent::SAVE},
347 {OHOS::NWeb::NWEB_AUTOFILL_EVENT_FILL, OHOS::NWeb::NWebAutofillEvent::FILL},
348 {OHOS::NWeb::NWEB_AUTOFILL_EVENT_UPDATE, OHOS::NWeb::NWebAutofillEvent::UPDATE},
349 {OHOS::NWeb::NWEB_AUTOFILL_EVENT_CLOSE, OHOS::NWeb::NWebAutofillEvent::CLOSE},
350 };
351
GetWebDebugBackGroundColor()352 std::string GetWebDebugBackGroundColor()
353 {
354 return OHOS::system::GetParameter("web.debug.surfaceNodeBackgroundColor", "");
355 }
356
IsSnapshotPathValid(const std::string & snapshotPath)357 bool IsSnapshotPathValid(const std::string& snapshotPath)
358 {
359 std::error_code ec;
360 std::filesystem::path canonicalPath = std::filesystem::canonical(snapshotPath, ec);
361 if (ec) {
362 TAG_LOGE(AceLogTag::ACE_WEB, "blankless canonical failed:%{public}s", ec.message().c_str());
363 return false;
364 }
365 // 4为后缀".png"的长度
366 if (snapshotPath.rfind(WEB_SNAPSHOT_PATH_PREFIX, 0) != 0 ||
367 snapshotPath.length() <= 4 || snapshotPath.rfind(WEB_SNAPSHOT_PATH_SUFFIX) != snapshotPath.length() - 4) {
368 TAG_LOGE(AceLogTag::ACE_WEB, "blankless the path or the format is wrong:%{public}s", snapshotPath.c_str());
369 return false;
370 }
371 if (!std::filesystem::exists(canonicalPath, ec)) {
372 TAG_LOGE(AceLogTag::ACE_WEB, "blankless canonical path:%{public}s does not exist:%{public}s",
373 snapshotPath.c_str(), ec.message().c_str());
374 return false;
375 }
376 return true;
377 }
378 } // namespace
379
PipStartPipCallback(uint32_t controllerId,uint8_t requestId,uint64_t surfaceId)380 void PipStartPipCallback(uint32_t controllerId, uint8_t requestId, uint64_t surfaceId)
381 {
382 TAG_LOGI(AceLogTag::ACE_WEB, "PipStartPipCallback %{public}u", controllerId);
383 if (g_currentControllerId != controllerId) {
384 TAG_LOGE(AceLogTag::ACE_WEB, "The controllerId is not equal %{public}u", g_currentControllerId);
385 return;
386 }
387 std::lock_guard<std::mutex> lock(pipCallbackMapMutex_);
388 auto it = pipCallbackMap_.find(controllerId);
389 if (it != pipCallbackMap_.end()) {
390 auto pip = it->second;
391
392 OHNativeWindow *window = nullptr;
393 int32_t ret = OH_NativeWindow_CreateNativeWindowFromSurfaceId(surfaceId, &window);
394 if (ret != GSERROR_OK) {
395 TAG_LOGI(AceLogTag::ACE_WEB, "CreateNativeWindowFromSurfaceId err:%{public}d ", ret);
396 return;
397 }
398 if (window == nullptr) {
399 TAG_LOGI(AceLogTag::ACE_WEB, "CreateNativeWindowFromSurfaceId window is null");
400 return;
401 }
402 if (pip.pipWebPattern) {
403 pip.pipWebPattern->SetPipNativeWindow(pip.delegateId, pip.childId, pip.frameRoutingId, window);
404 }
405 }
406 }
407
PipLifecycleCallback(uint32_t controllerId,PictureInPicture_PipState state,int32_t errorCode)408 void PipLifecycleCallback(uint32_t controllerId, PictureInPicture_PipState state, int32_t errorCode)
409 {
410 TAG_LOGI(AceLogTag::ACE_WEB, "PipLifeCycleCallback, controllerId:%{public}u, "
411 "PipState:%{public}d, errorCode:%{public}d", controllerId, state, errorCode);
412 if (g_currentControllerId != controllerId || g_currentControllerIdStop) {
413 g_currentControllerIdStop = false;
414 TAG_LOGE(AceLogTag::ACE_WEB, "The controllerId is not equal %{public}u", g_currentControllerId);
415 return;
416 }
417 uint32_t event;
418 {
419 std::lock_guard<std::mutex> lock(pipCallbackMapMutex_);
420 auto it = pipCallbackMap_.find(controllerId);
421 if (it != pipCallbackMap_.end()) {
422 switch (state) {
423 case PictureInPicture_PipState::STOPPED:
424 if (it->second.preStatus != PictureInPicture_PipState::ABOUT_TO_RESTORE) {
425 event = PIP_STATE_EXIT;
426 } else {
427 event = PIP_STATE_NONE;
428 }
429 break;
430 case PictureInPicture_PipState::ABOUT_TO_RESTORE:
431 event = PIP_STATE_RESTORE;
432 break;
433 default:
434 event = PIP_STATE_NONE;
435 }
436 if (event != PIP_STATE_NONE) {
437 auto pip = it->second;
438 if (pip.pipWebPattern) {
439 pip.pipWebPattern->SendPipEvent(pip.delegateId, pip.childId, pip.frameRoutingId, event);
440 }
441 }
442 if (state != PictureInPicture_PipState::ABOUT_TO_STOP) {
443 it->second.preStatus = state;
444 }
445 }
446 }
447 }
448
PipControlEventCallback(uint32_t controllerId,PictureInPicture_PipControlType actionType,PictureInPicture_PipControlStatus status)449 void PipControlEventCallback(
450 uint32_t controllerId, PictureInPicture_PipControlType actionType, PictureInPicture_PipControlStatus status)
451 {
452 TAG_LOGI(AceLogTag::ACE_WEB, "PipControlEventCallback, controllerId:%{public}u,"
453 "actionType:%{public}d, status:%{public}d", controllerId, actionType, status);
454 if (g_currentControllerId != controllerId) {
455 TAG_LOGE(AceLogTag::ACE_WEB, "The controllerId is not equal %{public}u", g_currentControllerId);
456 return;
457 }
458 uint32_t event;
459 switch (actionType) {
460 case PictureInPicture_PipControlType::VIDEO_PLAY_PAUSE:
461 event = status == 0 ? PIP_STATE_PAUSE : PIP_STATE_PLAY;
462 break;
463 case PictureInPicture_PipControlType::FAST_FORWARD:
464 event = PIP_STATE_FAST_FORWARD;
465 break;
466 case PictureInPicture_PipControlType::FAST_BACKWARD:
467 event = PIP_STATE_FAST_BACKWARD;
468 break;
469 default:
470 event = PIP_STATE_NONE;
471 }
472 if (event != PIP_STATE_NONE) {
473 std::lock_guard<std::mutex> lock(pipCallbackMapMutex_);
474 auto it = pipCallbackMap_.find(controllerId);
475 if (it != pipCallbackMap_.end()) {
476 auto pip = it->second;
477 if (pip.pipWebPattern) {
478 pip.pipWebPattern->SendPipEvent(pip.delegateId, pip.childId, pip.frameRoutingId, event);
479 }
480 }
481 }
482 }
483
PipResizeCallback(uint32_t controllerId,uint32_t width,uint32_t height,double scale)484 void PipResizeCallback(uint32_t controllerId, uint32_t width, uint32_t height, double scale)
485 {
486 TAG_LOGI(AceLogTag::ACE_WEB, "PipResizeCallback, controllerId:%{public}u, "
487 "width:%{public}d, height:%{public}d", controllerId, width, height);
488 if (g_currentControllerId != controllerId) {
489 TAG_LOGE(AceLogTag::ACE_WEB, "The controllerId is not equal %{public}u", g_currentControllerId);
490 return;
491 }
492
493 std::lock_guard<std::mutex> lock(pipCallbackMapMutex_);
494 auto it = pipCallbackMap_.find(controllerId);
495 if (it != pipCallbackMap_.end()) {
496 auto pip = it->second;
497 if (pip.pipWebPattern) {
498 pip.pipWebPattern->SendPipEvent(
499 pip.delegateId, pip.childId, pip.frameRoutingId, PIP_STATE_RESIZE);
500 }
501 }
502 }
503
504 constexpr int32_t SINGLE_CLICK_NUM = 1;
505 constexpr int32_t DOUBLE_CLICK_NUM = 2;
506 constexpr int32_t TRIPLE_CLICK_NUM = 3;
507 constexpr double DEFAULT_DBCLICK_INTERVAL = 0.5;
508 constexpr double DEFAULT_DBCLICK_OFFSET = 2.0;
509 constexpr double DEFAULT_AXIS_RATIO = -12.5;
510 constexpr double DEFAULT_WEB_WIDTH = 100.0;
511 constexpr double DEFAULT_WEB_HEIGHT = 80.0;
512 constexpr Dimension TOOLTIP_BORDER_WIDTH = 1.0_vp;
513 constexpr Dimension TOOLTIP_BORDER_RADIUS = 8.0_vp;
514 constexpr Dimension TOOLTIP_FONT_SIZE = 14.0_vp;
515 constexpr Dimension TOOLTIP_PADDING = 8.0_vp;
516 constexpr float TOOLTIP_MAX_PORTION = 0.35f;
517 constexpr float TOOLTIP_MARGIN = 10.0f;
518 constexpr float TOOLTIP_DELAY_MS = 700;
519 constexpr uint32_t ADJUST_WEB_DRAW_LENGTH = 3000;
520 constexpr int32_t FIT_CONTENT_LIMIT_LENGTH = 8000;
521 const std::string PATTERN_TYPE_WEB = "WEBPATTERN";
522 const std::string BUFFER_USAGE_SURFACE = "web-surface-";
523 const std::string BUFFER_USAGE_TEXTURE = "web-texture-";
524 const std::string DEFAULT_WEB_TEXT_ENCODING_FORMAT = "UTF-8";
525 constexpr int32_t SYNC_SURFACE_QUEUE_SIZE = 8;
526 constexpr int32_t ASYNC_SURFACE_QUEUE_SIZE_FOR_PHONE_AND_PC = 5;
527 constexpr int32_t ASYNC_SURFACE_QUEUE_SIZE_FOR_OTHERS = 4;
528 constexpr uint32_t DEBUG_DRAGMOVEID_TIMER = 30;
529 // web feature params
530 constexpr char VISIBLE_ACTIVE_ENABLE[] = "persist.web.visible_active_enable";
531 constexpr char MEMORY_LEVEL_ENABEL[] = "persist.web.memory_level_enable";
532 const std::vector<std::string> SYNC_RENDER_SLIDE {V2::LIST_ETS_TAG, V2::SCROLL_ETS_TAG};
533
534 constexpr int32_t DEFAULT_PINCH_FINGER = 2;
535 constexpr double DEFAULT_PINCH_DISTANCE = 6.0;
536 constexpr double DEFAULT_PINCH_SCALE = 1.0;
537 constexpr double DEFAULT_PINCH_SCALE_MAX = 5.0;
538 constexpr double DEFAULT_PINCH_SCALE_MIN = 0.1;
539 constexpr int32_t STATUS_ZOOMIN = 1;
540 constexpr int32_t STATUS_ZOOMOUT = 2;
541 constexpr int32_t ZOOM_ERROR_COUNT_MAX = 5;
542 constexpr double ZOOMIN_PUBLIC_ERRAND = 0.4444;
543 constexpr int32_t ZOOM_CONVERT_NUM = 10;
544 constexpr int32_t POPUP_CALCULATE_RATIO = 2;
545 constexpr int32_t MIN_ACCESSIBILITY_FOCUS_SIZE = 2;
546
547 constexpr int32_t PINCH_START_TYPE = 1;
548 constexpr int32_t PINCH_UPDATE_TYPE = 3;
549 constexpr int32_t PINCH_END_TYPE = 2;
550 constexpr int32_t PINCH_CANCEL_TYPE = 4;
551
552 constexpr char ACCESSIBILITY_GENERIC_CONTAINER[] = "genericContainer";
553 constexpr char ACCESSIBILITY_IMAGE[] = "image";
554 constexpr char ACCESSIBILITY_PARAGRAPH[] = "paragraph";
555 constexpr char WEB_NODE_URL[] = "url";
556
557 const std::string IS_HINT_TYPE = "{\"isHint2Type\": true}";
558 const std::string STRING_LF = "\n";
559 const std::string DRAG_DATA_TYPE_TEXT = "general.plain-text";
560 const std::string DRAG_DATA_TYPE_HTML = "general.html";
561 const std::string DRAG_DATA_TYPE_APP_DEF = "ApplicationDefinedType";
562 const std::set<std::string> FILE_TYPE_SET = {"general.file", "general.audio", "general.video", "general.image"};
563 const std::string DRAG_DATA_TYPE_LINK = "general.hyperlink";
564 const std::string FAKE_DRAG_DATA_VAL = " ";
565 const std::string FAKE_LINK_VAL = "https://xxx.xxx.xxx";
566
567 #define WEB_ACCESSIBILITY_DELAY_TIME 100
568 #define GPU_ABNORMAL_VALUE (32 * 1024)
569 #define GPU_SERIOUS_ABNORMAL_VALUE (32 * 1024 * 1024)
570 #define SIZE_UNIT 1024
571 #define FLOAT_UNIT 100.0F
572 #define DECIMAL_POINTS 2
573 #define WEB_CHECK_FALSE_RETURN CHECK_NULL_RETURN
574
575 using Recorder::EventRecorder;
576
WebPattern()577 WebPattern::WebPattern()
578 {
579 InitMagnifier();
580 renderMode_ = RenderMode::ASYNC_RENDER;
581 cursorType_ = OHOS::NWeb::CursorType::CT_NONE;
582 viewDataCommon_ = std::make_shared<ViewDataCommon>();
583 InitRotationEventCallback();
584 }
585
WebPattern(const std::string & webSrc,const RefPtr<WebController> & webController,RenderMode renderMode,bool incognitoMode,const std::string & sharedRenderProcessToken)586 WebPattern::WebPattern(const std::string& webSrc, const RefPtr<WebController>& webController, RenderMode renderMode,
587 bool incognitoMode, const std::string& sharedRenderProcessToken)
588 : webSrc_(std::move(webSrc)), webController_(webController), renderMode_(renderMode), incognitoMode_(incognitoMode),
589 sharedRenderProcessToken_(sharedRenderProcessToken)
590 {
591 InitMagnifier();
592 cursorType_ = OHOS::NWeb::CursorType::CT_NONE;
593 viewDataCommon_ = std::make_shared<ViewDataCommon>();
594 InitRotationEventCallback();
595 }
596
WebPattern(const std::string & webSrc,const SetWebIdCallback & setWebIdCallback,RenderMode renderMode,bool incognitoMode,const std::string & sharedRenderProcessToken)597 WebPattern::WebPattern(const std::string& webSrc, const SetWebIdCallback& setWebIdCallback, RenderMode renderMode,
598 bool incognitoMode, const std::string& sharedRenderProcessToken)
599 : webSrc_(std::move(webSrc)), setWebIdCallback_(setWebIdCallback), renderMode_(renderMode),
600 incognitoMode_(incognitoMode), sharedRenderProcessToken_(sharedRenderProcessToken)
601 {
602 InitMagnifier();
603 cursorType_ = OHOS::NWeb::CursorType::CT_NONE;
604 viewDataCommon_ = std::make_shared<ViewDataCommon>();
605 InitRotationEventCallback();
606 }
607
~WebPattern()608 WebPattern::~WebPattern()
609 {
610 TAG_LOGI(AceLogTag::ACE_WEB, "NWEB ~WebPattern start");
611 ACE_SCOPED_TRACE("WebPattern::~WebPattern, web id = %d", GetWebId());
612 UninitTouchEventListener();
613 if (setWebDetachCallback_) {
614 auto setWebDetachTask = [callback = setWebDetachCallback_, webId = GetWebId()]() {
615 CHECK_NULL_VOID(callback);
616 callback(webId);
617 };
618 PostTaskToUI(std::move(setWebDetachTask), "ArkUIWebviewControllerSetWebDetachTask");
619 }
620 if (delegate_) {
621 TAG_LOGD(AceLogTag::ACE_WEB, "NWEB ~WebPattern delegate_ start SetAudioMuted");
622 delegate_->SetAudioMuted(true);
623 delegate_->UnRegisterNativeArkJSFunction(Recorder::WEB_OBJ_NAME);
624 }
625
626 if (observer_) {
627 TAG_LOGD(AceLogTag::ACE_WEB, "NWEB ~WebPattern observer_ start NotifyDestory");
628 observer_->NotifyDestory();
629 }
630 if (isActive_) {
631 TAG_LOGD(AceLogTag::ACE_WEB, "NWEB ~WebPattern isActive_ start OnInActive");
632 SetActiveStatusInner(false, true);
633 }
634 if (imageAnalyzerManager_) {
635 imageAnalyzerManager_->ReleaseImageAnalyzer();
636 }
637 UninitializeAccessibility();
638 HideMagnifier();
639 OnTooltip("");
640
641 {
642 std::lock_guard<std::mutex> lock(pipCallbackMapMutex_);
643 for (auto& it: pipController_) {
644 OH_PictureInPicture_UnregisterAllResizeListeners(it);
645 OH_PictureInPicture_DeletePip(it);
646 pipCallbackMap_.erase(it);
647 }
648 pipController_.clear();
649 }
650 UninitRotationEventCallback();
651 }
652
ShowContextSelectOverlay(const RectF & firstHandle,const RectF & secondHandle,TextResponseType responseType,bool handleReverse)653 void WebPattern::ShowContextSelectOverlay(const RectF& firstHandle, const RectF& secondHandle,
654 TextResponseType responseType, bool handleReverse)
655 {
656 if (contextSelectOverlay_) {
657 contextSelectOverlay_->ProcessOverlay({ .animation = true });
658 }
659 }
660
CloseContextSelectionMenu()661 void WebPattern::CloseContextSelectionMenu()
662 {
663 if (contextSelectOverlay_ && contextSelectOverlay_->IsCurrentMenuVisibile()) {
664 contextSelectOverlay_->CloseOverlay(true, CloseReason::CLOSE_REASON_NORMAL);
665 }
666 }
667
RemovePreviewMenuNode()668 void WebPattern::RemovePreviewMenuNode()
669 {
670 if (!previewImageNodeId_.has_value()) {
671 return;
672 }
673 TAG_LOGI(AceLogTag::ACE_WEB, "RemovePreviewMenuNode");
674 curContextMenuResult_ = false;
675 auto previewNode =
676 FrameNode::GetFrameNode(V2::IMAGE_ETS_TAG, previewImageNodeId_.value());
677 CHECK_NULL_VOID(previewNode);
678 auto parent = previewNode->GetParent();
679 CHECK_NULL_VOID(parent);
680 parent->RemoveChild(previewNode);
681 previewImageNodeId_.reset();
682 parent->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
683 }
684
IsPreviewMenuNotNeedShowPreview()685 bool WebPattern::IsPreviewMenuNotNeedShowPreview()
686 {
687 bool isNotNeedShowPreview =
688 ((isNewDragStyle_ || isAILinkMenuShow_) && IsPreviewImageNodeExist()) || imageOverlayIsSelected_;
689 TAG_LOGI(AceLogTag::ACE_WEB,
690 "IsPreviewMenuNotNeedShowPreview:%{public}d, for AI link preview menu %{public}d, for AI entity popup: "
691 "%{public}d",
692 isNotNeedShowPreview, isAILinkMenuShow_, imageOverlayIsSelected_);
693 return isNotNeedShowPreview;
694 }
695
SetPreviewSelectionMenu(const std::shared_ptr<WebPreviewSelectionMenuParam> & param)696 void WebPattern::SetPreviewSelectionMenu(const std::shared_ptr<WebPreviewSelectionMenuParam>& param)
697 {
698 CHECK_NULL_VOID(param);
699 auto onPreviewMenuDisappear = [weak = AceType::WeakClaim(this),
700 onDisappear = std::move(param->menuParam.onDisappear)]() {
701 TAG_LOGD(AceLogTag::ACE_WEB, "onPreviewMenuDisappear");
702 if (onDisappear) {
703 onDisappear();
704 }
705 auto webPattern = weak.Upgrade();
706 CHECK_NULL_VOID(webPattern);
707 webPattern->RemovePreviewMenuNode();
708 CHECK_NULL_VOID(webPattern->contextMenuResult_);
709 webPattern->contextMenuResult_->Cancel();
710 webPattern->SetAILinkMenuShow(false);
711 };
712 param->menuParam.onDisappear = std::move(onPreviewMenuDisappear);
713 auto key = std::make_pair(param->type, param->responseType);
714 auto it = previewSelectionMenuMap_.find(key);
715 if (it != previewSelectionMenuMap_.end()) {
716 if (param->menuBuilder == nullptr) {
717 previewSelectionMenuMap_.erase(it);
718 return;
719 }
720 it->second = param;
721 return;
722 }
723 previewSelectionMenuMap_[key] = param;
724 TAG_LOGD(AceLogTag::ACE_WEB, "muneParam hapticFeedbackMode:%{public}d", param->menuParam.hapticFeedbackMode);
725 }
726
GetPreviewSelectionMenuParams(const WebElementType & type,const ResponseType & responseType)727 std::shared_ptr<WebPreviewSelectionMenuParam> WebPattern::GetPreviewSelectionMenuParams(
728 const WebElementType& type, const ResponseType& responseType)
729 {
730 auto key = std::make_pair(type, responseType);
731 auto it = previewSelectionMenuMap_.find(key);
732 if (it != previewSelectionMenuMap_.end()) {
733 return it->second;
734 }
735
736 TAG_LOGD(AceLogTag::ACE_WEB, "The key not in previewSelectionMenuMap_");
737 return nullptr;
738 }
739
GetPreviewImageOffsetAndSize(bool isImage,Offset & previewOffset,SizeF & previewSize)740 void WebPattern::GetPreviewImageOffsetAndSize(bool isImage, Offset& previewOffset, SizeF& previewSize)
741 {
742 CHECK_NULL_VOID(contextMenuParam_);
743 int32_t x = 0;
744 int32_t y = 0;
745 int32_t width = 0;
746 int32_t height = 0;
747 contextMenuParam_->GetImageRect(x, y, width, height);
748 if (isImage) {
749 previewOffset.SetX((float)x);
750 previewOffset.SetY((float)y);
751 previewSize.SetWidth((float)width);
752 previewSize.SetHeight((float)height);
753 } else {
754 previewOffset.SetX((float)x);
755 previewOffset.SetY((float)y);
756 if (width == 0 && height == 0) {
757 previewSize.SetWidth(drawSize_.Width());
758 previewSize.SetHeight(drawSize_.Height());
759 } else {
760 previewSize.SetWidth((float)width);
761 previewSize.SetHeight((float)height);
762 }
763 }
764 auto host = GetHost();
765 CHECK_NULL_VOID(host);
766 auto pipeline = host->GetContextRefPtr();
767 CHECK_NULL_VOID(pipeline);
768 previewSize.SetWidth(previewSize.Width() / pipeline->GetDipScale());
769 previewSize.SetHeight(previewSize.Height() / pipeline->GetDipScale());
770 }
771
CreatePreviewImageFrameNode(bool isImage)772 RefPtr<FrameNode> WebPattern::CreatePreviewImageFrameNode(bool isImage)
773 {
774 RemovePreviewMenuNode();
775 previewImageNodeId_ = ElementRegister::GetInstance()->MakeUniqueId();
776 auto previewNode = FrameNode::GetOrCreateFrameNode(
777 V2::IMAGE_ETS_TAG, previewImageNodeId_.value(), []() { return AceType::MakeRefPtr<ImagePattern>(); });
778 CHECK_NULL_RETURN(previewNode, nullptr);
779 auto previewRenderContext = previewNode->GetRenderContext();
780 CHECK_NULL_RETURN(previewRenderContext, nullptr);
781 auto previewGesture = previewNode->GetOrCreateGestureEventHub();
782 CHECK_NULL_RETURN(previewGesture, nullptr);
783
784 previewNode->SetDraggable(false);
785 previewGesture->SetDragEvent(nullptr, { PanDirection::DOWN }, 0, Dimension(0));
786
787 Offset previewOffset(0, 0);
788 SizeF previewSize;
789 GetPreviewImageOffsetAndSize(isImage, previewOffset, previewSize);
790 if (previewSize.Width() <= 0 || previewSize.Height() <= 0) {
791 TAG_LOGI(AceLogTag::ACE_WEB, "CreatePreviewImageFrameNode get preview size(%{public}f, %{public}f) error",
792 previewSize.Width(), previewSize.Height());
793 return nullptr;
794 }
795 previewRenderContext->UpdatePosition(
796 OffsetT<Dimension>(Dimension(previewOffset.GetX()), Dimension(previewOffset.GetY())));
797
798 auto previewProperty = previewNode->GetLayoutProperty<ImageLayoutProperty>();
799 previewProperty->UpdateAutoResize(false);
800 previewProperty->UpdateMarginSelfIdealSize(previewSize);
801 MeasureProperty layoutConstraint;
802 CalcSize idealSize = { CalcLength(Dimension(previewSize.Width(), DimensionUnit::VP).ConvertToPx()),
803 CalcLength(Dimension(previewSize.Height(), DimensionUnit::VP).ConvertToPx()) };
804 layoutConstraint.selfIdealSize = idealSize;
805 layoutConstraint.maxSize = idealSize;
806 previewNode->UpdateLayoutConstraint(layoutConstraint);
807 TAG_LOGI(AceLogTag::ACE_WEB,
808 "CreatePreviewImageFrameNode offset:%{public}f, %{public}f; size:%{public}f, %{public}f",
809 previewOffset.GetX(), previewOffset.GetY(), previewSize.Width(), previewSize.Height());
810 needUpdateImagePreviewParam_ = true;
811 curContextMenuResult_ = true;
812 return previewNode;
813 }
814
CreateSnapshotImageFrameNode(const std::string & snapshotPath)815 void WebPattern::CreateSnapshotImageFrameNode(const std::string& snapshotPath)
816 {
817 TAG_LOGI(AceLogTag::ACE_WEB, "blankless WebPattern::CreateSnapshotImageFrameNode");
818 if (snapshotImageNodeId_.has_value()) {
819 TAG_LOGE(AceLogTag::ACE_WEB, "blankless already create snapshot image node!");
820 return;
821 }
822 if (!IsSnapshotPathValid(snapshotPath)) {
823 TAG_LOGE(AceLogTag::ACE_WEB, "blankless snapshot path is invalid!");
824 return;
825 }
826 snapshotImageNodeId_ = ElementRegister::GetInstance()->MakeUniqueId();
827 auto snapshotNode = FrameNode::GetOrCreateFrameNode(
828 V2::IMAGE_ETS_TAG, snapshotImageNodeId_.value(), []() { return AceType::MakeRefPtr<ImagePattern>(); });
829 CHECK_NULL_VOID(snapshotNode);
830 auto pattern = snapshotNode->GetPattern<ImagePattern>();
831 CHECK_NULL_VOID(pattern);
832 pattern->SetSyncLoad(true);
833
834 auto host = GetHost();
835 CHECK_NULL_VOID(host);
836 auto index = host->GetChildren().size();
837 snapshotNode->MountToParent(host, index);
838
839 snapshotNode->SetDraggable(false);
840 auto gesture = snapshotNode->GetOrCreateGestureEventHub();
841 CHECK_NULL_VOID(gesture);
842 gesture->SetDragEvent(nullptr, { PanDirection::DOWN }, 0, Dimension(0));
843
844 auto imageLayoutProperty = snapshotNode->GetLayoutProperty<ImageLayoutProperty>();
845 CHECK_NULL_VOID(imageLayoutProperty);
846 ImageSourceInfo sourceInfo = ImageSourceInfo("file://" + snapshotPath);
847 imageLayoutProperty->UpdateImageSourceInfo(sourceInfo);
848 snapshotNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
849 snapshotNode->MarkModifyDone();
850 }
851
RemoveSnapshotFrameNode()852 void WebPattern::RemoveSnapshotFrameNode()
853 {
854 if (!snapshotImageNodeId_.has_value()) {
855 return;
856 }
857 TAG_LOGI(AceLogTag::ACE_WEB, "blankless RemoveSnapshotFrameNode");
858 auto snapshotNode = FrameNode::GetFrameNode(V2::IMAGE_ETS_TAG, snapshotImageNodeId_.value());
859 snapshotImageNodeId_.reset();
860 CHECK_NULL_VOID(snapshotNode);
861 auto parent = snapshotNode->GetParent();
862 CHECK_NULL_VOID(parent);
863 parent->RemoveChild(snapshotNode);
864 parent->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
865 }
866
SetActiveStatusInner(bool isActive,bool isForce)867 void WebPattern::SetActiveStatusInner(bool isActive, bool isForce)
868 {
869 TAG_LOGI(AceLogTag::ACE_WEB,
870 "WebPattern::SetActiveStatusInner webId:%{public}d, isActive_:%{public}d, isActive:%{public}d, "
871 "isForce:%{public}d",
872 GetWebId(), isActive_, isActive, isForce);
873 if (!isForce) {
874 if (isActive == isActive_) {
875 return;
876 }
877
878 if (delegate_ && delegate_->IsActivePolicyDisable()) {
879 TAG_LOGW(AceLogTag::ACE_WEB, "ArkWeb is IsActivePolicyDisable");
880 return;
881 }
882 }
883 isActive_ = isActive;
884 if (delegate_) {
885 isActive ? delegate_->OnActive() : delegate_->OnInactive();
886 }
887 }
888
UpdateImagePreviewParam()889 void WebPattern::UpdateImagePreviewParam()
890 {
891 CHECK_NULL_VOID(needUpdateImagePreviewParam_);
892 needUpdateImagePreviewParam_ = false;
893 if (!previewImageNodeId_.has_value()) {
894 return;
895 }
896 TAG_LOGI(AceLogTag::ACE_WEB, "UpdateImagePreviewParam");
897 auto params = GetPreviewSelectionMenuParams(curElementType_, curResponseType_);
898 if (!params) {
899 RemovePreviewMenuNode();
900 return;
901 }
902 #ifndef ACE_UNITTEST
903 auto previewNode =
904 FrameNode::GetFrameNode(V2::IMAGE_ETS_TAG, previewImageNodeId_.value());
905 CHECK_NULL_VOID(previewNode);
906 if (curElementType_ == WebElementType::AILINK && GetDataDetectorEnable()) {
907 if (!webDataDetectorAdapter_->GetPreviewMenuBuilder(params->menuBuilder, params->previewBuilder)) {
908 return;
909 }
910 }
911 ViewStackProcessor::GetInstance()->Push(previewNode);
912 ViewAbstractModel::GetInstance()->BindContextMenu(
913 curResponseType_, params->menuBuilder, params->menuParam, params->previewBuilder);
914 ViewAbstractModel::GetInstance()->BindDragWithContextMenuParams(params->menuParam);
915 ViewStackProcessor::GetInstance()->Finish();
916 #endif
917 }
918
ShowPreviewMenu(WebElementType type)919 void WebPattern::ShowPreviewMenu(WebElementType type) {
920 auto sourceType = contextMenuParam_->GetSourceType();
921 if (sourceType == OHOS::NWeb::NWebContextMenuParams::ContextMenuSourceType::CM_ST_MOUSE) {
922 curResponseType_ = ResponseType::RIGHT_CLICK;
923 } else if (sourceType == OHOS::NWeb::NWebContextMenuParams::ContextMenuSourceType::CM_ST_LONG_PRESS) {
924 curResponseType_ = ResponseType::LONG_PRESS;
925 } else {
926 return;
927 }
928 curElementType_ = type;
929 CHECK_NULL_VOID(GetPreviewSelectionMenuParams(curElementType_, curResponseType_));
930 auto host = GetHost();
931 if (!host) {
932 TAG_LOGE(AceLogTag::ACE_WEB, "GetHost failed");
933 CHECK_NULL_VOID(delegate_);
934 delegate_->OnContextMenuHide("");
935 return;
936 }
937 auto previewNode = CreatePreviewImageFrameNode(type == WebElementType::IMAGE);
938 if (!previewNode) {
939 TAG_LOGI(AceLogTag::ACE_WEB, "CreatePreviewImageFrameNode failed");
940 previewImageNodeId_.reset();
941 CHECK_NULL_VOID(delegate_);
942 delegate_->OnContextMenuHide("");
943 return;
944 }
945 isAILinkMenuShow_ = (type == WebElementType::AILINK);
946 TAG_LOGI(AceLogTag::ACE_WEB, "ShowPreviewMenu for AI link: %{public}d", isAILinkMenuShow_);
947 host->AddChild(previewNode);
948 previewNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
949 previewNode->MarkModifyDone();
950 host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
951 host->MarkModifyDone();
952 }
953
OnContextMenuShow(const std::shared_ptr<BaseEventInfo> & info,bool isRichtext,bool result)954 void WebPattern::OnContextMenuShow(const std::shared_ptr<BaseEventInfo>& info, bool isRichtext, bool result)
955 {
956 TAG_LOGI(AceLogTag::ACE_WEB,
957 "OnContextMenuShow result:%{public}d, isNewDragStyle_:%{public}d", result, isNewDragStyle_);
958 curContextMenuResult_ = result;
959 auto *eventInfo = TypeInfoHelper::DynamicCast<ContextMenuEvent>(info.get());
960 CHECK_NULL_VOID(eventInfo);
961 contextMenuParam_ = eventInfo->GetParam();
962 CHECK_NULL_VOID(contextMenuParam_);
963 contextMenuResult_ = eventInfo->GetContextMenuResult();
964 CHECK_NULL_VOID(contextMenuResult_);
965 bool isImage = false;
966 bool isHyperLink = false;
967 bool isAILink = !contextMenuParam_->GetLinkUrl().empty() && contextMenuParam_->IsAILink() &&
968 GetDataDetectorEnable() && webDataDetectorAdapter_->GetDataDetectorEnablePrewiew();
969 auto copyOption =
970 delegate_ ? delegate_->GetCopyOptionMode() : OHOS::NWeb::NWebPreference::CopyOptionMode::LOCAL_DEVICE;
971 isAILink = isAILink && copyOption != OHOS::NWeb::NWebPreference::CopyOptionMode::NONE;
972 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWENTY)) {
973 CHECK_NULL_VOID(delegate_);
974 int hitTestResult = delegate_->GetLastHitTestResult();
975 TAG_LOGI(AceLogTag::ACE_WEB, "OnContextMenuShow hitTestResult:%{public}d, isAILink:%{public}d", hitTestResult,
976 contextMenuParam_->IsAILink());
977 switch (static_cast<WebHitTestType>(hitTestResult)) {
978 case WebHitTestType::IMG:
979 isImage = true;
980 break;
981 case WebHitTestType::HTTP_IMG:
982 isImage = true;
983 isHyperLink = true;
984 break;
985 case WebHitTestType::HTTP:
986 isHyperLink = true;
987 break;
988 default:
989 break;
990 }
991
992 // since async hittest, reconfirm
993 isImage = isImage && contextMenuParam_->GetMediaType() ==
994 OHOS::NWeb::NWebContextMenuParams::ContextMenuMediaType::CM_MT_IMAGE;
995 isHyperLink =
996 isHyperLink && !isImage && !contextMenuParam_->GetLinkUrl().empty() && !contextMenuParam_->IsAILink();
997 } else {
998 isImage = (contextMenuParam_->GetLinkUrl().empty() &&
999 (contextMenuParam_->GetMediaType() ==
1000 OHOS::NWeb::NWebContextMenuParams::ContextMenuMediaType::CM_MT_IMAGE));
1001 }
1002 if (isRichtext) {
1003 if (!contextSelectOverlay_) {
1004 contextSelectOverlay_ = AceType::MakeRefPtr<WebContextSelectOverlay>(WeakClaim(this));
1005 }
1006 ShowContextSelectOverlay(RectF(), RectF());
1007 return;
1008 }
1009 CHECK_NULL_VOID((isNewDragStyle_ || isAILink) && result);
1010 TAG_LOGD(AceLogTag::ACE_WEB, "OnContextMenuShow isImage:%{public}d, isHyperLink:%{public}d", isImage, isHyperLink);
1011 if (isImage) {
1012 ShowPreviewMenu(WebElementType::IMAGE);
1013 } else if (isHyperLink) {
1014 ShowPreviewMenu(WebElementType::LINK);
1015 } else if (isAILink) {
1016 CHECK_NULL_VOID(webDataDetectorAdapter_);
1017 if (!webDataDetectorAdapter_->SetPreviewMenuLink(contextMenuParam_->GetLinkUrl())) {
1018 return;
1019 }
1020 ShowPreviewMenu(WebElementType::AILINK);
1021 }
1022 }
1023
OnContextMenuHide()1024 void WebPattern::OnContextMenuHide()
1025 {
1026 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern OnContextMenuHide");
1027 isAILinkMenuShow_ = false;
1028 if (webData_) {
1029 CloseContextSelectionMenu();
1030 return;
1031 }
1032 RemovePreviewMenuNode();
1033 CHECK_NULL_VOID(contextMenuResult_);
1034 contextMenuResult_->Cancel();
1035 curContextMenuResult_ = false;
1036 }
1037
NeedSoftKeyboard() const1038 bool WebPattern::NeedSoftKeyboard() const
1039 {
1040 if (delegate_) {
1041 return delegate_->NeedSoftKeyboard();
1042 }
1043 return false;
1044 }
1045
EnableSecurityLayer(bool isNeedSecurityLayer)1046 void WebPattern::EnableSecurityLayer(bool isNeedSecurityLayer)
1047 {
1048 if (!renderContextForSurface_) {
1049 TAG_LOGE(AceLogTag::ACE_WEB, "WebPattern::EnableSecurityLayer, renderContextForSurface_ is null");
1050 return;
1051 }
1052 renderContextForSurface_->SetSecurityLayer(isNeedSecurityLayer);
1053 }
1054
OnAttachToMainTree()1055 void WebPattern::OnAttachToMainTree()
1056 {
1057 TAG_LOGI(AceLogTag::ACE_WEB, "OnAttachToMainTree WebId %{public}d", GetWebId());
1058 isAttachedToMainTree_ = true;
1059 InitSlideUpdateListener();
1060 // report component is in foreground.
1061 delegate_->OnRenderToForeground();
1062
1063 if (delegate_->GetPageFinishedState()) {
1064 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::OnAttachToMainTree delegate_ pageFinishedState is true");
1065 return;
1066 }
1067 auto host = GetHost();
1068 CHECK_NULL_VOID(host);
1069 auto pipeline = PipelineContext::GetCurrentContext();
1070 CHECK_NULL_VOID(pipeline);
1071 auto frontend = pipeline->GetFrontend();
1072 CHECK_NULL_VOID(frontend);
1073 auto accessibilityManager = frontend->GetAccessibilityManager();
1074 CHECK_NULL_VOID(accessibilityManager);
1075 accessibilityManager->AddToPageEventController(host);
1076 }
1077
OnDetachFromMainTree()1078 void WebPattern::OnDetachFromMainTree()
1079 {
1080 TAG_LOGI(AceLogTag::ACE_WEB, "OnDetachFromMainTree WebId %{public}d", GetWebId());
1081 isAttachedToMainTree_ = false;
1082 // report component is in background.
1083 delegate_->OnRenderToBackground();
1084
1085 auto host = GetHost();
1086 CHECK_NULL_VOID(host);
1087 auto pipelineContext = host->GetContext();
1088 CHECK_NULL_VOID(pipelineContext);
1089 auto frontend = pipelineContext->GetFrontend();
1090 CHECK_NULL_VOID(frontend);
1091 auto accessibilityManager = frontend->GetAccessibilityManager();
1092 CHECK_NULL_VOID(accessibilityManager);
1093 accessibilityManager->ReleasePageEvent(host, true, false);
1094 }
1095
OnAttachToFrameNode()1096 void WebPattern::OnAttachToFrameNode()
1097 {
1098 auto host = GetHost();
1099 CHECK_NULL_VOID(host);
1100 auto pipeline = PipelineContext::GetCurrentContext();
1101 CHECK_NULL_VOID(pipeline);
1102 SetRotation(pipeline->GetTransformHint());
1103
1104 host->GetRenderContext()->UpdateClipEdge(true);
1105 if (!renderContextForSurface_) {
1106 renderContextForSurface_ = RenderContext::Create();
1107 static RenderContext::ContextParam param = { RenderContext::ContextType::HARDWARE_SURFACE,
1108 "RosenWeb" };
1109 CHECK_NULL_VOID(renderContextForSurface_);
1110 renderContextForSurface_->InitContext(false, param);
1111 // Disable hardware composition when initializing to fix visual artifacts when switching to a new webview.
1112 auto surfaceNode = OHOS::Rosen::RSBaseNode::ReinterpretCast<OHOS::Rosen::RSSurfaceNode>(GetSurfaceRSNode());
1113 CHECK_NULL_VOID(surfaceNode);
1114 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::OnAttachToFrameNode, web id = %{public}d", GetWebId());
1115 ACE_SCOPED_TRACE("WebPattern::OnAttachToFrameNode, web id = %d", GetWebId());
1116 surfaceNode->SetHardwareEnabled(true, Rosen::SelfDrawingNodeType::DEFAULT, false);
1117 }
1118
1119 if (!renderContextForPopupSurface_) {
1120 renderContextForPopupSurface_ = RenderContext::Create();
1121 CHECK_NULL_VOID(renderContextForPopupSurface_);
1122 static RenderContext::ContextParam popupParam = { RenderContext::ContextType::HARDWARE_SURFACE,
1123 "RosenWebPopup" };
1124 renderContextForPopupSurface_->InitContext(false, popupParam);
1125 }
1126 host->GetLayoutProperty()->UpdateMeasureType(MeasureType::MATCH_PARENT);
1127 pipeline->AddNodesToNotifyMemoryLevel(host->GetId());
1128
1129 auto callbackId = pipeline->RegisterTransformHintChangeCallback([weak = WeakClaim(this)](uint32_t transform) {
1130 auto pattern = weak.Upgrade();
1131 if (pattern) {
1132 TAG_LOGD(AceLogTag::ACE_WEB, "OnAttach to frame node, set transform:%{public}u", transform);
1133 pattern->SetRotation(transform);
1134 }
1135 });
1136 UpdateTransformHintChangedCallbackId(callbackId);
1137 #if !defined(PREVIEW) && !defined(ACE_UNITTEST) && defined(OHOS_PLATFORM)
1138 if (UiSessionManager::GetInstance()->GetWebFocusRegistered()) {
1139 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::OnAttachToFrameNode, register event report callback");
1140 auto report = GetAccessibilityEventReport();
1141 CHECK_NULL_VOID(report);
1142 report->RegisterAllReportEventCallBack();
1143 }
1144 pipeline->RegisterListenerForTranslate(WeakClaim(RawPtr(host)));
1145 EventRecorder::Get().OnAttachWeb(host);
1146 #endif
1147 }
1148
OnDetachFromFrameNode(FrameNode * frameNode)1149 void WebPattern::OnDetachFromFrameNode(FrameNode* frameNode)
1150 {
1151 CHECK_NULL_VOID(delegate_);
1152 isFocus_ = false;
1153 delegate_->OnBlur();
1154 OnQuickMenuDismissed();
1155
1156 auto id = frameNode->GetId();
1157 auto pipeline = AceType::DynamicCast<PipelineContext>(PipelineBase::GetCurrentContext());
1158 CHECK_NULL_VOID(pipeline);
1159 pipeline->RemoveWindowStateChangedCallback(id);
1160 pipeline->RemoveWindowSizeChangeCallback(id);
1161 pipeline->RemoveNodesToNotifyMemoryLevel(id);
1162
1163 if (HasTransformHintChangedCallbackId()) {
1164 pipeline->UnregisterTransformHintChangedCallback(transformHintChangedCallbackId_.value_or(-1));
1165 }
1166 #if !defined(PREVIEW) && !defined(ACE_UNITTEST) && defined(OHOS_PLATFORM)
1167 if (UiSessionManager::GetInstance()->GetWebFocusRegistered()) {
1168 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::OnDetachFromFrameNode UnRegisterCallback");
1169 auto report = GetAccessibilityEventReport();
1170 CHECK_NULL_VOID(report);
1171 report->UnRegisterCallback();
1172 }
1173 pipeline->UnRegisterListenerForTranslate(id);
1174 EventRecorder::Get().OnDetachWeb(id);
1175 #endif
1176 }
1177
SetRotation(uint32_t rotation)1178 void WebPattern::SetRotation(uint32_t rotation)
1179 {
1180 if (renderMode_ == RenderMode::SYNC_RENDER || rotation_ == rotation) {
1181 return;
1182 }
1183 rotation_ = rotation;
1184 CHECK_NULL_VOID(renderSurface_);
1185 renderSurface_->SetTransformHint(rotation);
1186 CHECK_NULL_VOID(delegate_);
1187 delegate_->SetTransformHint(rotation);
1188 }
1189
InitEvent()1190 void WebPattern::InitEvent()
1191 {
1192 auto host = GetHost();
1193 CHECK_NULL_VOID(host);
1194 auto eventHub = host->GetOrCreateEventHub<WebEventHub>();
1195 CHECK_NULL_VOID(eventHub);
1196
1197 auto gestureHub = eventHub->GetOrCreateGestureEventHub();
1198 CHECK_NULL_VOID(gestureHub);
1199
1200 InitTouchEvent(gestureHub);
1201 InitDragEvent(gestureHub);
1202 InitPanEvent(gestureHub);
1203 InitPinchEvent(gestureHub);
1204
1205 auto inputHub = eventHub->GetOrCreateInputEventHub();
1206 CHECK_NULL_VOID(inputHub);
1207 InitMouseEvent(inputHub);
1208 InitHoverEvent(inputHub);
1209
1210 auto focusHub = eventHub->GetOrCreateFocusHub();
1211 CHECK_NULL_VOID(focusHub);
1212 InitFocusEvent(focusHub);
1213 }
1214
InitConfigChangeCallback(const RefPtr<PipelineContext> & context)1215 void WebPattern::InitConfigChangeCallback(const RefPtr<PipelineContext> &context)
1216 {
1217 auto langTask = [weak = AceType::WeakClaim(this)]() {
1218 auto WebPattern = weak.Upgrade();
1219 CHECK_NULL_VOID(WebPattern);
1220 WebPattern->UpdateLocale();
1221 };
1222 context->SetConfigChangedCallback(GetHost()->GetId(), std::move(langTask));
1223 }
1224
InitFeatureParam()1225 void WebPattern::InitFeatureParam()
1226 {
1227 isVisibleActiveEnable_ = system::GetBoolParameter(VISIBLE_ACTIVE_ENABLE, true);
1228 isMemoryLevelEnable_ = system::GetBoolParameter(MEMORY_LEVEL_ENABEL, true);
1229 }
1230
InitPanEvent(const RefPtr<GestureEventHub> & gestureHub)1231 void WebPattern::InitPanEvent(const RefPtr<GestureEventHub>& gestureHub)
1232 {
1233 if (panEvent_) {
1234 return;
1235 }
1236 auto actionStartTask = [weak = WeakClaim(this)](const GestureEvent& event) {
1237 auto pattern = weak.Upgrade();
1238 CHECK_NULL_VOID(pattern);
1239 // Determine if there is already a fixed nested scroll mode.
1240 if (!pattern->GetIsFixedNestedScrollMode() || !pattern->GetNestedScrollParent()) {
1241 pattern->SetParentScrollable();
1242 }
1243 pattern->UpdateTouchpadSlidingStatus(event);
1244 pattern->GetParentAxis();
1245 };
1246 auto actionUpdateTask = [weak = WeakClaim(this)](const GestureEvent& event) {
1247 auto pattern = weak.Upgrade();
1248 CHECK_NULL_VOID(pattern);
1249 pattern->HandleDragMove(event);
1250 };
1251 auto actionEndTask = [weak = WeakClaim(this)](const GestureEvent& info) {
1252 auto pattern = weak.Upgrade();
1253 CHECK_NULL_VOID(pattern);
1254 pattern->HandleFlingMove(info);
1255 };
1256 auto actionCancelTask = [weak = WeakClaim(this)]() { return; };
1257 PanDirection panDirection;
1258 panDirection.type = PanDirection::ALL;
1259 panEvent_ = MakeRefPtr<PanEvent>(
1260 std::move(actionStartTask), std::move(actionUpdateTask), std::move(actionEndTask), std::move(actionCancelTask));
1261 PanDistanceMap distanceMap = { { SourceTool::UNKNOWN, DEFAULT_PAN_DISTANCE.ConvertToPx() },
1262 { SourceTool::PEN, DEFAULT_PEN_PAN_DISTANCE.ConvertToPx() } };
1263 gestureHub->AddPanEvent(panEvent_, panDirection, DEFAULT_PAN_FINGER, distanceMap);
1264 gestureHub->SetPanEventType(GestureTypeName::WEBSCROLL);
1265 gestureHub->SetOnGestureJudgeNativeBegin([](const RefPtr<NG::GestureInfo>& gestureInfo,
1266 const std::shared_ptr<BaseGestureEvent>& info) -> GestureJudgeResult {
1267 if (!gestureInfo) {
1268 // info is null, default case to continue
1269 return GestureJudgeResult::CONTINUE;
1270 }
1271 if (gestureInfo->GetType() != GestureTypeName::WEBSCROLL) {
1272 // not web pan event type, continue
1273 return GestureJudgeResult::CONTINUE;
1274 }
1275 auto inputEventType = gestureInfo->GetInputEventType();
1276 if (inputEventType == InputEventType::AXIS) {
1277 // axis event type of web pan, dispatch to panEvent to process
1278 return GestureJudgeResult::CONTINUE;
1279 } else if (inputEventType == InputEventType::MOUSE_BUTTON) {
1280 // mouse button event type of web pan, dispatch to DragEvent to process
1281 return GestureJudgeResult::REJECT;
1282 }
1283 // In other cases, the panEvent is used by default
1284 return GestureJudgeResult::CONTINUE;
1285 });
1286 }
1287
HandleFlingMove(const GestureEvent & event)1288 void WebPattern::HandleFlingMove(const GestureEvent& event)
1289 {
1290 if (snapshotImageNodeId_.has_value()) {
1291 TAG_LOGD(AceLogTag::ACE_WEB, "blankless during snapshot image, no need to handle fling move!");
1292 return;
1293 }
1294 if ((event.GetInputEventType() == InputEventType::AXIS) &&
1295 (event.GetSourceTool() == SourceTool::TOUCHPAD)) {
1296 CHECK_NULL_VOID(delegate_);
1297 std::vector<int32_t> pressedCodes;
1298 auto gesturePressedCodes = event.GetPressedKeyCodes();
1299 for (auto pCode : gesturePressedCodes) {
1300 pressedCodes.push_back(static_cast<int32_t>(pCode));
1301 }
1302 auto localLocation = event.GetLocalLocation();
1303 delegate_->WebHandleTouchpadFlingEvent(localLocation.GetX(), localLocation.GetY(),
1304 event.GetVelocity().GetVelocityX(),
1305 event.GetVelocity().GetVelocityY(),
1306 pressedCodes);
1307 }
1308 }
1309
HandleDragMove(const GestureEvent & event)1310 void WebPattern::HandleDragMove(const GestureEvent& event)
1311 {
1312 if (snapshotImageNodeId_.has_value()) {
1313 TAG_LOGD(AceLogTag::ACE_WEB, "blankless during snapshot image, no need to handle drag move!");
1314 return;
1315 }
1316 if (event.GetInputEventType() == InputEventType::AXIS) {
1317 CHECK_NULL_VOID(delegate_);
1318 auto localLocation = event.GetLocalLocation();
1319 std::vector<int32_t> pressedCodes;
1320 auto gesturePressedCodes = event.GetPressedKeyCodes();
1321 for (auto pCode : gesturePressedCodes) {
1322 pressedCodes.push_back(static_cast<int32_t>(pCode));
1323 }
1324 TAG_LOGD(AceLogTag::ACE_WEB, "HandleDragMove Axis deltaX: %{public}f deltaY: %{public}f",
1325 event.GetDelta().GetX(), event.GetDelta().GetY());
1326 delegate_->WebHandleAxisEvent(localLocation.GetX(), localLocation.GetY(),
1327 event.GetDelta().GetX() / DEFAULT_AXIS_RATIO, event.GetDelta().GetY() / DEFAULT_AXIS_RATIO,
1328 pressedCodes, static_cast<int32_t>(event.GetSourceTool()));
1329 }
1330 }
1331
InitPinchEvent(const RefPtr<GestureEventHub> & gestureHub)1332 void WebPattern::InitPinchEvent(const RefPtr<GestureEventHub>& gestureHub)
1333 {
1334 if (pinchGesture_) {
1335 if (gestureHub->WillRecreateGesture()) {
1336 gestureHub->AddGesture(pinchGesture_);
1337 }
1338 return;
1339 }
1340 auto actionStartTask = [weak = WeakClaim(this)](const GestureEvent& event) {
1341 if (event.GetSourceTool() == SourceTool::TOUCHPAD) {
1342 auto pattern = weak.Upgrade();
1343 CHECK_NULL_VOID(pattern);
1344 pattern->startPageScale_ = pattern->pageScale_;
1345 TAG_LOGD(AceLogTag::ACE_WEB, "InitPinchEvent actionStartTask startPageScale: %{public}f",
1346 pattern->startPageScale_);
1347
1348 pattern->startPinchScale_ = event.GetScale();
1349 pattern->preScale_ = pattern->startPinchScale_;
1350 pattern->zoomOutSwitch_ = false;
1351 pattern->zoomStatus_ = 0;
1352 pattern->zoomErrorCount_ = 0;
1353 TAG_LOGD(AceLogTag::ACE_WEB, "InitPinchEvent actionStartTask startPinchScale: %{public}f",
1354 pattern->startPinchScale_);
1355
1356 pattern->HandleScaleGestureStart(event);
1357 }
1358 };
1359 auto actionUpdateTask = [weak = WeakClaim(this)](const GestureEvent& event) {
1360 ACE_SCOPED_TRACE("WebPattern::InitPinchEvent actionUpdateTask");
1361 if (event.GetSourceTool() == SourceTool::TOUCHPAD) {
1362 auto pattern = weak.Upgrade();
1363 CHECK_NULL_VOID(pattern);
1364 TAG_LOGD(AceLogTag::ACE_WEB, "InitPinchEvent actionUpdateTask event scale:%{public}f: ", event.GetScale());
1365 pattern->HandleScaleGestureChange(event);
1366 }
1367 };
1368 auto actionEndTask = [weak = WeakClaim(this)](const GestureEvent& event) {
1369 if (event.GetSourceTool() == SourceTool::TOUCHPAD) {
1370 auto pattern = weak.Upgrade();
1371 CHECK_NULL_VOID(pattern);
1372 pattern->HandleScaleGestureEnd(event);
1373 }
1374 };
1375 auto actionCancelTask = [weak = WeakClaim(this)](const GestureEvent& event) {
1376 if (event.GetSourceTool() == SourceTool::TOUCHPAD) {
1377 auto pattern = weak.Upgrade();
1378 CHECK_NULL_VOID(pattern);
1379 pattern->HandleScaleGestureCancel(event);
1380 }
1381 };
1382
1383 pinchGesture_ = MakeRefPtr<PinchGesture>(DEFAULT_PINCH_FINGER, DEFAULT_PINCH_DISTANCE);
1384 pinchGesture_->SetPriority(GesturePriority::Parallel);
1385 pinchGesture_->SetOnActionStartId(actionStartTask);
1386 pinchGesture_->SetOnActionUpdateId(actionUpdateTask);
1387 pinchGesture_->SetOnActionEndId(actionEndTask);
1388 pinchGesture_->SetOnActionCancelId(actionCancelTask);
1389 gestureHub->AddGesture(pinchGesture_);
1390 }
1391
CheckZoomStatus(const double & curScale)1392 bool WebPattern::CheckZoomStatus(const double& curScale)
1393 {
1394 int32_t curScaleNew = (int32_t)(curScale * 100);
1395 int32_t preScaleNew = (int32_t)(preScale_ * 100);
1396
1397 // check zoom status
1398 if ((zoomStatus_ == STATUS_ZOOMOUT && curScaleNew - preScaleNew < 0) && zoomErrorCount_ < ZOOM_ERROR_COUNT_MAX) {
1399 zoomErrorCount_++;
1400 TAG_LOGI(AceLogTag::ACE_WEB, "CheckZoomStatus zoomStatus = zoomout && curScale < preScale,"
1401 "ignore date.");
1402 return false;
1403 } else if ((zoomStatus_ == STATUS_ZOOMIN && curScaleNew - preScaleNew > 0) &&
1404 zoomErrorCount_ < ZOOM_ERROR_COUNT_MAX) {
1405 zoomErrorCount_++;
1406 TAG_LOGI(AceLogTag::ACE_WEB, "CheckZoomStatus zoomStatus = zoomin && curScale >= preScale,"
1407 "ignore date.");
1408 return false;
1409 } else {
1410 // nothing
1411 }
1412 return true;
1413 }
1414
ZoomOutAndIn(const double & curScale,double & scale)1415 bool WebPattern::ZoomOutAndIn(const double& curScale, double& scale)
1416 {
1417 int32_t curScaleNew = (int32_t)(curScale * 100);
1418 int32_t preScaleNew = (int32_t)(preScale_ * 100);
1419
1420 // zoom out
1421 if (GreatOrEqual(curScale, preScale_)) {
1422 if (GreatOrEqual(preScale_, DEFAULT_PINCH_SCALE)) {
1423 // start page scale > 1
1424 if (GreatOrEqual(curScale, DEFAULT_PINCH_SCALE) && !zoomOutSwitch_) {
1425 scale = curScale * startPageScale_;
1426
1427 TAG_LOGD(AceLogTag::ACE_WEB, "ZoomOutAndIn curScale * pageScale_= %{public}f", scale);
1428 } else {
1429 TAG_LOGD(AceLogTag::ACE_WEB, "ZoomOutAndIn curScale < DEFAULT_PINCH_SCALE");
1430 scale = DEFAULT_PINCH_SCALE + (curScale - startPinchScale_);
1431 }
1432 } else {
1433 // The scale is from 0.4 to 0.5, the scale conversion should be from 1.0 to 1.1
1434 // once
1435 if (zoomStatus_ == STATUS_ZOOMIN) {
1436 TAG_LOGI(AceLogTag::ACE_WEB, "ZoomOutAndIn Switch from zoomin to zoomout.");
1437 // must be page scale form 0.4 to 1
1438 scale = pageScale_;
1439 // reset
1440 startPinchScale_ = preScale_;
1441 zoomOutSwitch_ = true;
1442 } else {
1443 TAG_LOGD(AceLogTag::ACE_WEB, "ZoomOutAndIn zoomStatus_ = STATUS_ZOOMOUT curScale < 1.0");
1444 scale = DEFAULT_PINCH_SCALE + (curScale - startPinchScale_);
1445 }
1446 }
1447 zoomStatus_ = STATUS_ZOOMOUT;
1448 // zoom in
1449 } else {
1450 // from zoonout to zoomin
1451 if (zoomStatus_ == STATUS_ZOOMOUT) {
1452 TAG_LOGI(AceLogTag::ACE_WEB, "ZoomOutAndIn Switch from zoomout to zoomin.");
1453 // reset
1454 startPinchScale_ = preScale_;
1455 zoomOutSwitch_ = false;
1456 }
1457
1458 if (curScaleNew == preScaleNew) {
1459 TAG_LOGI(AceLogTag::ACE_WEB, "ZoomOutAndIn curScaleNew == preScaleNew");
1460 return false;
1461 }
1462
1463 scale = curScale;
1464
1465 zoomStatus_ = STATUS_ZOOMIN;
1466 }
1467 return true;
1468 }
1469
HandleScaleGestureChange(const GestureEvent & event)1470 void WebPattern::HandleScaleGestureChange(const GestureEvent& event)
1471 {
1472 if (snapshotImageNodeId_.has_value()) {
1473 TAG_LOGD(AceLogTag::ACE_WEB, "blankless during snapshot image, no need to handle scale gesture change!");
1474 return;
1475 }
1476 CHECK_NULL_VOID(delegate_);
1477
1478 double curScale = event.GetScale();
1479 if (NearEqual(curScale, preScale_)) {
1480 TAG_LOGI(AceLogTag::ACE_WEB, "HandleScaleGestureChange curScale == preScale");
1481 return;
1482 }
1483
1484 if (LessOrEqual(curScale, 0.0) || LessOrEqual(preScale_, 0.0)) {
1485 TAG_LOGE(AceLogTag::ACE_WEB, "HandleScaleGestureChange invalid scale");
1486 return;
1487 }
1488
1489 TAG_LOGD(AceLogTag::ACE_WEB,
1490 "HandleScaleGestureChange curScale:%{public}f, preScale: %{public}f, "
1491 "zoomStatus: %{public}d, pageScale: %{public}f, startPinchScale: %{public}f, startPageScale: %{public}f",
1492 curScale, preScale_, zoomStatus_, pageScale_, startPinchScale_, startPageScale_);
1493
1494 if (!CheckZoomStatus(curScale)) {
1495 return;
1496 }
1497
1498 zoomErrorCount_ = 0;
1499
1500 double newScale = curScale / preScale_;
1501 double newOriginScale = GetNewOriginScale(event.GetScale());
1502
1503 double centerX = event.GetPinchCenter().GetX();
1504 double centerY = event.GetPinchCenter().GetY();
1505 auto frameNode = GetHost();
1506 CHECK_NULL_VOID(frameNode);
1507 auto offset = frameNode->GetOffsetRelativeToWindow();
1508 TAG_LOGD(AceLogTag::ACE_WEB,
1509 "HandleScaleGestureChangeV2 curScale:%{public}f newScale: %{public}f"
1510 " centerX: %{public}f centerY: %{public}f",
1511 curScale, newScale, centerX, centerY);
1512
1513 // Plan two
1514 delegate_->ScaleGestureChangeV2(
1515 PINCH_UPDATE_TYPE, newScale, newOriginScale, centerX - offset.GetX(), centerY - offset.GetY());
1516
1517 preScale_ = curScale;
1518 }
1519
getZoomOffset(double & scale) const1520 double WebPattern::getZoomOffset(double& scale) const
1521 {
1522 double offset = DEFAULT_PINCH_SCALE - scale;
1523 if (LessOrEqual(offset, 0.0)) {
1524 TAG_LOGE(AceLogTag::ACE_WEB, "getZoomOffset curScale < preScale");
1525 return 0.0;
1526 }
1527 return offset * ZOOM_CONVERT_NUM * ZOOMIN_PUBLIC_ERRAND;
1528 }
1529
GetNewScale(double & scale) const1530 double WebPattern::GetNewScale(double& scale) const
1531 {
1532 if (GreatOrEqual(scale, DEFAULT_PINCH_SCALE_MAX)) {
1533 scale = DEFAULT_PINCH_SCALE_MAX;
1534
1535 TAG_LOGE(AceLogTag::ACE_WEB, "GetNewScale scale > DEFAULT_PINCH_SCALE_MAX");
1536 return DEFAULT_PINCH_SCALE;
1537 }
1538
1539 double newScale = 0.0;
1540 if (GreatOrEqual(scale, DEFAULT_PINCH_SCALE)) {
1541 // In order to achieve a sequence similar to scale, eg. 1.1, 1.2, 1.3
1542 if (zoomStatus_ == STATUS_ZOOMOUT) {
1543 newScale = scale / pageScale_;
1544 // scale > 1.0 when scale form zoomout to zoomin
1545 } else if (zoomStatus_ == STATUS_ZOOMIN) {
1546 scale = startPageScale_ * scale;
1547 if (GreatNotEqual(scale, 0.0)) {
1548 newScale = scale / pageScale_;
1549 } else {
1550 newScale = DEFAULT_PINCH_SCALE_MIN;
1551 scale = DEFAULT_PINCH_SCALE;
1552
1553 TAG_LOGE(AceLogTag::ACE_WEB, "GetNewScale scale < 0.0");
1554 }
1555 }
1556
1557 // scale max
1558 if (GreatOrEqual(newScale, DEFAULT_PINCH_SCALE_MAX)) {
1559 newScale = DEFAULT_PINCH_SCALE_MAX;
1560 scale = DEFAULT_PINCH_SCALE_MAX;
1561
1562 TAG_LOGI(AceLogTag::ACE_WEB, "GetNewScale newScale > DEFAULT_PINCH_SCALE_MAX");
1563 }
1564 } else {
1565 TAG_LOGD(AceLogTag::ACE_WEB, "GetNewScale getZoomOffset:%{public}f", getZoomOffset(scale));
1566
1567 scale = startPageScale_ - getZoomOffset(scale);
1568 if (GreatNotEqual(scale, 0.0)) {
1569 newScale = scale / pageScale_;
1570 } else {
1571 newScale = DEFAULT_PINCH_SCALE_MIN;
1572 scale = DEFAULT_PINCH_SCALE;
1573
1574 TAG_LOGE(AceLogTag::ACE_WEB, "GetNewScale scale < 0.0");
1575 }
1576
1577 TAG_LOGD(AceLogTag::ACE_WEB,
1578 "GetNewScale scale: %{public}f, newScale: %{public}f, pageScale: %{public}f, startPageScale: %{public}f",
1579 scale, newScale, pageScale_, startPageScale_);
1580 }
1581
1582 // scale min
1583 if (LessNotEqual(newScale, DEFAULT_PINCH_SCALE_MIN)) {
1584 newScale = DEFAULT_PINCH_SCALE_MIN;
1585 scale = DEFAULT_PINCH_SCALE;
1586
1587 TAG_LOGE(AceLogTag::ACE_WEB, "GetNewScale newScale < DEFAULT_PINCH_SCALE_MIN");
1588 }
1589
1590 return newScale;
1591 }
1592
GetNewOriginScale(double originScale) const1593 double WebPattern::GetNewOriginScale(double originScale) const
1594 {
1595 double newScale = 0.0;
1596 if (zoomStatus_ == STATUS_ZOOMOUT) {
1597 newScale = DEFAULT_PINCH_SCALE_MAX;
1598 } else if (zoomStatus_ == STATUS_ZOOMIN) {
1599 newScale = DEFAULT_PINCH_SCALE_MIN;
1600 }
1601
1602 return newScale;
1603 }
1604
HandleScaleGestureStart(const GestureEvent & event)1605 void WebPattern::HandleScaleGestureStart(const GestureEvent& event)
1606 {
1607 if (snapshotImageNodeId_.has_value()) {
1608 TAG_LOGD(AceLogTag::ACE_WEB, "blankless during snapshot image, no need to handle scale gesture start!");
1609 return;
1610 }
1611 CHECK_NULL_VOID(delegate_);
1612
1613 double scale = event.GetScale();
1614
1615 double centerX = event.GetPinchCenter().GetX();
1616 double centerY = event.GetPinchCenter().GetY();
1617 auto frameNode = GetHost();
1618 CHECK_NULL_VOID(frameNode);
1619 auto offset = frameNode->GetOffsetRelativeToWindow();
1620
1621 delegate_->ScaleGestureChangeV2(
1622 PINCH_START_TYPE, scale, event.GetScale(), centerX - offset.GetX(), centerY - offset.GetY());
1623 }
1624
HandleScaleGestureEnd(const GestureEvent & event)1625 void WebPattern::HandleScaleGestureEnd(const GestureEvent& event)
1626 {
1627 if (snapshotImageNodeId_.has_value()) {
1628 TAG_LOGD(AceLogTag::ACE_WEB, "blankless during snapshot image, no need to handle scale gesture end!");
1629 return;
1630 }
1631 CHECK_NULL_VOID(delegate_);
1632
1633 double scale = event.GetScale();
1634
1635 double centerX = event.GetPinchCenter().GetX();
1636 double centerY = event.GetPinchCenter().GetY();
1637 auto frameNode = GetHost();
1638 CHECK_NULL_VOID(frameNode);
1639 auto offset = frameNode->GetOffsetRelativeToWindow();
1640
1641 delegate_->ScaleGestureChangeV2(
1642 PINCH_END_TYPE, scale, event.GetScale(), centerX - offset.GetX(), centerY - offset.GetY());
1643 }
1644
HandleScaleGestureCancel(const GestureEvent & event)1645 void WebPattern::HandleScaleGestureCancel(const GestureEvent& event)
1646 {
1647 if (snapshotImageNodeId_.has_value()) {
1648 TAG_LOGD(AceLogTag::ACE_WEB, "blankless during snapshot image, no need to handle scale gesture cancel!");
1649 return;
1650 }
1651 CHECK_NULL_VOID(delegate_);
1652
1653 double scale = event.GetScale();
1654
1655 double centerX = event.GetPinchCenter().GetX();
1656 double centerY = event.GetPinchCenter().GetY();
1657 auto frameNode = GetHost();
1658 CHECK_NULL_VOID(frameNode);
1659 auto offset = frameNode->GetOffsetRelativeToWindow();
1660
1661 delegate_->ScaleGestureChangeV2(
1662 PINCH_CANCEL_TYPE, scale, event.GetScale(), centerX - offset.GetX(), centerY - offset.GetY());
1663 }
1664
InitTouchEvent(const RefPtr<GestureEventHub> & gestureHub)1665 void WebPattern::InitTouchEvent(const RefPtr<GestureEventHub>& gestureHub)
1666 {
1667 if (touchEvent_) {
1668 return;
1669 }
1670
1671 auto touchTask = [weak = WeakClaim(this)](const TouchEventInfo& info) {
1672 auto pattern = weak.Upgrade();
1673 CHECK_NULL_VOID(pattern);
1674 pattern->OnTooltip("");
1675 if (info.GetChangedTouches().empty()) {
1676 return;
1677 }
1678
1679 // only handle touch event
1680 if (info.GetSourceDevice() != SourceType::TOUCH) {
1681 return;
1682 }
1683 pattern->isMouseEvent_ = false;
1684 pattern->HandleTouchEvent(info);
1685 };
1686 touchEvent_ = MakeRefPtr<TouchEventImpl>(std::move(touchTask));
1687 gestureHub->AddTouchEvent(touchEvent_);
1688 }
1689
InitMouseEvent(const RefPtr<InputEventHub> & inputHub)1690 void WebPattern::InitMouseEvent(const RefPtr<InputEventHub>& inputHub)
1691 {
1692 if (mouseEvent_) {
1693 return;
1694 }
1695
1696 auto mouseTask = [weak = WeakClaim(this)](MouseInfo& info) {
1697 auto pattern = weak.Upgrade();
1698 CHECK_NULL_VOID(pattern);
1699 TouchEventInfo touchEventInfo("touchEvent");
1700 if (EventInfoConvertor::ConvertMouseToTouchIfNeeded(info, touchEventInfo)) {
1701 TAG_LOGI(AceLogTag::ACE_WEB, "Convert mouse event to touch event: button %{public}d, action %{public}d.",
1702 (int)info.GetButton(), (int)info.GetAction());
1703 touchEventInfo.SetTouchEventsEnd(true);
1704 pattern->HandleTouchEvent(touchEventInfo);
1705 return;
1706 }
1707 pattern->HandleMouseEvent(info);
1708 };
1709
1710 mouseEvent_ = MakeRefPtr<InputEvent>(std::move(mouseTask));
1711 inputHub->AddOnMouseEvent(mouseEvent_);
1712 }
1713
InitHoverEvent(const RefPtr<InputEventHub> & inputHub)1714 void WebPattern::InitHoverEvent(const RefPtr<InputEventHub>& inputHub)
1715 {
1716 if (hoverEvent_) {
1717 return;
1718 }
1719
1720 auto hoverTask = [weak = WeakClaim(this)](bool isHover) {
1721 auto pattern = weak.Upgrade();
1722 CHECK_NULL_VOID(pattern);
1723 MouseInfo info;
1724 info.SetAction(isHover ? MouseAction::HOVER : MouseAction::HOVER_EXIT);
1725 pattern->WebOnMouseEvent(info);
1726 };
1727
1728 hoverEvent_ = MakeRefPtr<InputEvent>(std::move(hoverTask));
1729 inputHub->AddOnHoverEvent(hoverEvent_);
1730 }
1731
HandleTouchEvent(const TouchEventInfo & info)1732 void WebPattern::HandleTouchEvent(const TouchEventInfo& info)
1733 {
1734 if (snapshotImageNodeId_.has_value()) {
1735 TAG_LOGD(AceLogTag::ACE_WEB, "blankless during snapshot image, no need to handle touch event!");
1736 return;
1737 }
1738 touchEventInfo_ = info;
1739 const auto& changedPoint = info.GetChangedTouches().front();
1740 if (changedPoint.GetTouchType() == TouchType::DOWN ||
1741 changedPoint.GetTouchType() == TouchType::UP) {
1742 if (touchEventQueue_.size() < TOUCH_EVENT_MAX_SIZE) {
1743 touchEventQueue_.push(info);
1744 }
1745 }
1746
1747 if (changedPoint.GetTouchType() == TouchType::DOWN) {
1748 HandleTouchDown(info, false);
1749 return;
1750 }
1751 if (changedPoint.GetTouchType() == TouchType::MOVE) {
1752 HandleTouchMove(info, false);
1753 return;
1754 }
1755 if (changedPoint.GetTouchType() == TouchType::UP) {
1756 HandleTouchUp(info, false);
1757 return;
1758 }
1759 if (changedPoint.GetTouchType() == TouchType::CANCEL) {
1760 HandleTouchCancel(info);
1761 return;
1762 }
1763 }
1764
HandleMouseEvent(MouseInfo & info)1765 void WebPattern::HandleMouseEvent(MouseInfo& info)
1766 {
1767 if (snapshotImageNodeId_.has_value()) {
1768 TAG_LOGD(AceLogTag::ACE_WEB, "blankless during snapshot image, no need to handle mouse event!");
1769 return;
1770 }
1771 if (info.GetAction() != MouseAction::MOVE) {
1772 TAG_LOGI(AceLogTag::ACE_WEB,
1773 "WebPattern::HandleMouseEvent, web id %{public}d, Action %{public}d, Button %{public}d",
1774 GetWebId(), static_cast<int32_t>(info.GetAction()), static_cast<int32_t>(info.GetButton()));
1775 }
1776
1777 ACE_SCOPED_TRACE(
1778 "WebPattern::HandleMouseEvent, web id %d, Action %d, Button %d",
1779 GetWebId(), static_cast<int32_t>(info.GetAction()), static_cast<int32_t>(info.GetButton()));
1780
1781 isMouseEvent_ = true;
1782 mouseInfo_ = info;
1783 if (info.GetButton() == MouseButton::LEFT_BUTTON
1784 && (info.GetAction() == MouseAction::PRESS || info.GetAction() == MouseAction::RELEASE)) {
1785 if (mouseInfoQueue_.size() < MOUSE_EVENT_MAX_SIZE) {
1786 mouseInfoQueue_.push(info);
1787 }
1788 }
1789 WebOnMouseEvent(info);
1790
1791 auto host = GetHost();
1792 CHECK_NULL_VOID(host);
1793 auto eventHub = host->GetOrCreateEventHub<WebEventHub>();
1794 CHECK_NULL_VOID(eventHub);
1795
1796 auto button = static_cast<MouseButton>(info.GetButton());
1797 bool isSupportMouse = button == MouseButton::LEFT_BUTTON
1798 || button == MouseButton::RIGHT_BUTTON || button == MouseButton::MIDDLE_BUTTON;
1799 if (delegate_ && delegate_->HasOnNativeEmbedGestureEventV2() && isSupportMouse) {
1800 auto gestureHub = eventHub->GetOrCreateGestureEventHub();
1801 CHECK_NULL_VOID(gestureHub);
1802 if (info.GetAction() == MouseAction::PRESS) {
1803 // start RecognizerDelay
1804 gestureHub->SetRecognizerDelayStatus(RecognizerDelayStatus::START);
1805 } else if (info.GetAction() == MouseAction::RELEASE) {
1806 gestureHub->SetRecognizerDelayStatus(RecognizerDelayStatus::NONE);
1807 }
1808 }
1809
1810 auto mouseEventCallback = eventHub->GetOnMouseEvent();
1811 CHECK_NULL_VOID(mouseEventCallback);
1812 mouseEventCallback(info);
1813 }
1814
WebOnMouseEvent(const MouseInfo & info)1815 void WebPattern::WebOnMouseEvent(const MouseInfo& info)
1816 {
1817 if (snapshotImageNodeId_.has_value()) {
1818 return;
1819 }
1820 if (mouseEventDeviceId_ != info.GetDeviceId()) {
1821 mouseEventDeviceId_ = info.GetDeviceId();
1822 }
1823 CHECK_NULL_VOID(delegate_);
1824 auto localLocation = info.GetLocalLocation();
1825 if ((info.GetAction() == MouseAction::PRESS) ||
1826 (info.GetButton() == MouseButton::LEFT_BUTTON) ||
1827 (info.GetButton() == MouseButton::RIGHT_BUTTON) ||
1828 (info.GetButton() == MouseButton::BACK_BUTTON) ||
1829 (info.GetButton() == MouseButton::FORWARD_BUTTON)) {
1830 OnTooltip("");
1831 }
1832 if (info.GetAction() == MouseAction::PRESS && !GetNativeEmbedModeEnabledValue(false)) {
1833 delegate_->OnContextMenuHide("");
1834 WebRequestFocus();
1835 }
1836
1837 // set touchup false when using mouse
1838 isTouchUpEvent_ = false;
1839 if (info.GetButton() == MouseButton::LEFT_BUTTON && info.GetAction() == MouseAction::RELEASE) {
1840 if (isReceivedArkDrag_) {
1841 TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop Do not reset drag action when dragging,"
1842 "drop/cancel/end event will do this");
1843 return;
1844 }
1845 ResetDragAction();
1846 }
1847 isHoverExit_ = false;
1848 if (info.GetAction() == MouseAction::HOVER_EXIT) {
1849 TAG_LOGI(AceLogTag::ACE_WEB,
1850 "Set cursor to pointer when mouse pointer is hover exit.");
1851 OnCursorChange(OHOS::NWeb::CursorType::CT_POINTER, nullptr);
1852 isHoverExit_ = true;
1853 MouseInfo changedInfo;
1854 changedInfo.SetAction(MouseAction::HOVER_EXIT);
1855 changedInfo.SetLocalLocation(Offset(mouseHoveredX_, mouseHoveredY_));
1856 WebSendMouseEvent(changedInfo, SINGLE_CLICK_NUM);
1857 return;
1858 } else if (info.GetAction() == MouseAction::HOVER && isMouseLocked_) {
1859 OnCursorChange(OHOS::NWeb::CursorType::CT_LOCK, nullptr);
1860 }
1861 int32_t clickNum = HandleMouseClickEvent(info);
1862
1863 WebSendMouseEvent(info, clickNum);
1864
1865 if (info.GetAction() == MouseAction::MOVE) {
1866 mouseHoveredX_ = localLocation.GetX();
1867 mouseHoveredY_ = localLocation.GetY();
1868 }
1869 }
1870
WebSendMouseEvent(const MouseInfo & info,int32_t clickNum)1871 void WebPattern::WebSendMouseEvent(const MouseInfo& info, int32_t clickNum)
1872 {
1873 if (delegate_->IsFileSelectorShow() && info.GetAction() == MouseAction::HOVER_EXIT) {
1874 TAG_LOGW(AceLogTag::ACE_WEB, "WebPattern::WebSendMouseEvent blocked when FileSelector show.");
1875 return;
1876 }
1877 std::vector<int32_t> pressedCodes {};
1878 std::vector<KeyCode> keyCode = info.GetPressedKeyCodes();
1879 for (auto pCode : keyCode) {
1880 pressedCodes.push_back(static_cast<int32_t>(pCode));
1881 }
1882
1883 std::shared_ptr<NWebMouseEventImpl> mouseEvent =
1884 std::make_shared<NWebMouseEventImpl>(info.GetLocalLocation().GetX(), info.GetLocalLocation().GetY(),
1885 info.GetGlobalLocation().GetX(), info.GetGlobalLocation().GetY(),
1886 static_cast<int32_t>(info.GetButton()), static_cast<int32_t>(info.GetAction()),
1887 clickNum, pressedCodes);
1888 delegate_->WebOnMouseEvent(mouseEvent);
1889 }
1890
ResetDragAction()1891 void WebPattern::ResetDragAction()
1892 {
1893 auto frameNode = GetHost();
1894 CHECK_NULL_VOID(frameNode);
1895 frameNode->SetDraggable(false);
1896 auto eventHub = frameNode->GetOrCreateEventHub<WebEventHub>();
1897 CHECK_NULL_VOID(eventHub);
1898 auto gestureHub = eventHub->GetOrCreateGestureEventHub();
1899 CHECK_NULL_VOID(gestureHub);
1900 gestureHub->ResetDragActionForWeb();
1901
1902 if (!isDragging_) {
1903 return;
1904 }
1905
1906 isDragging_ = false;
1907 isReceivedArkDrag_ = false;
1908 isDragStartFromWeb_ = false;
1909 // cancel drag action to avoid web kernel can't process other input event
1910 CHECK_NULL_VOID(delegate_);
1911 delegate_->HandleDragEvent(0, 0, DragAction::DRAG_CANCEL);
1912 gestureHub->CancelDragForWeb();
1913 }
1914
GetDragOffset() const1915 Offset WebPattern::GetDragOffset() const
1916 {
1917 Offset webDragOffset;
1918 int x = 0;
1919 int y = 0;
1920 if (delegate_ && delegate_->dragData_) {
1921 delegate_->dragData_->GetDragStartPosition(x, y);
1922 }
1923
1924 webDragOffset.SetX(x);
1925 webDragOffset.SetY(y);
1926
1927 return webDragOffset;
1928 }
1929
GetDragPixelMapSize() const1930 SizeF WebPattern::GetDragPixelMapSize() const
1931 {
1932 SizeF pixelMapSize;
1933 int32_t width = 0;
1934 int32_t height = 0;
1935 RefPtr<PixelMap> pixelMap = nullptr;
1936 if (delegate_) {
1937 pixelMap = delegate_->GetDragPixelMap();
1938 }
1939 if (pixelMap) {
1940 width = pixelMap->GetWidth();
1941 height = pixelMap->GetHeight();
1942 }
1943 pixelMapSize = SizeF(width, height);
1944 return pixelMapSize;
1945 }
1946
HandleMouseClickEvent(const MouseInfo & info)1947 int32_t WebPattern::HandleMouseClickEvent(const MouseInfo& info)
1948 {
1949 if (info.GetButton() != MouseButton::LEFT_BUTTON || info.GetAction() != MouseAction::PRESS) {
1950 return SINGLE_CLICK_NUM;
1951 }
1952 auto localLocation = info.GetLocalLocation();
1953 MouseClickInfo clickInfo;
1954 clickInfo.x = localLocation.GetX();
1955 clickInfo.y = localLocation.GetY();
1956 clickInfo.start = info.GetTimeStamp();
1957 if (mouseClickQueue_.empty()) {
1958 mouseClickQueue_.push(clickInfo);
1959 return SINGLE_CLICK_NUM;
1960 }
1961 std::chrono::duration<float> timeout_ = clickInfo.start - mouseClickQueue_.back().start;
1962 double offsetX = clickInfo.x - mouseClickQueue_.back().x;
1963 double offsetY = clickInfo.y - mouseClickQueue_.back().y;
1964 double offset = sqrt(offsetX * offsetX + offsetY * offsetY);
1965 if (timeout_.count() < DEFAULT_DBCLICK_INTERVAL && offset < DEFAULT_DBCLICK_OFFSET) {
1966 if (mouseClickQueue_.size() == SINGLE_CLICK_NUM) {
1967 mouseClickQueue_.push(clickInfo);
1968 return DOUBLE_CLICK_NUM;
1969 } else if (mouseClickQueue_.size() == DOUBLE_CLICK_NUM) {
1970 mouseClickQueue_.push(clickInfo);
1971 return TRIPLE_CLICK_NUM;
1972 } else if (mouseClickQueue_.size() == TRIPLE_CLICK_NUM) {
1973 mouseClickQueue_.pop();
1974 mouseClickQueue_.push(clickInfo);
1975 return TRIPLE_CLICK_NUM;
1976 }
1977 }
1978 if (mouseClickQueue_.size()) {
1979 std::queue<MouseClickInfo> empty;
1980 swap(empty, mouseClickQueue_);
1981 mouseClickQueue_.push(clickInfo);
1982 }
1983 return SINGLE_CLICK_NUM;
1984 }
1985
HandleDoubleClickEvent(const MouseInfo & info)1986 bool WebPattern::HandleDoubleClickEvent(const MouseInfo& info)
1987 {
1988 if (info.GetButton() != MouseButton::LEFT_BUTTON || info.GetAction() != MouseAction::PRESS) {
1989 return false;
1990 }
1991 auto localLocation = info.GetLocalLocation();
1992 MouseClickInfo clickInfo;
1993 clickInfo.x = localLocation.GetX();
1994 clickInfo.y = localLocation.GetY();
1995 clickInfo.start = info.GetTimeStamp();
1996 if (mouseClickQueue_.empty()) {
1997 mouseClickQueue_.push(clickInfo);
1998 return false;
1999 }
2000 std::chrono::duration<float> timeout_ = clickInfo.start - mouseClickQueue_.back().start;
2001 double offsetX = clickInfo.x - mouseClickQueue_.back().x;
2002 double offsetY = clickInfo.y - mouseClickQueue_.back().y;
2003 double offset = sqrt(offsetX * offsetX + offsetY * offsetY);
2004 if (timeout_.count() < DEFAULT_DBCLICK_INTERVAL && offset < DEFAULT_DBCLICK_OFFSET) {
2005 SendDoubleClickEvent(clickInfo);
2006 std::queue<MouseClickInfo> empty;
2007 swap(empty, mouseClickQueue_);
2008 return true;
2009 }
2010 if (mouseClickQueue_.size() == 1) {
2011 mouseClickQueue_.push(clickInfo);
2012 return false;
2013 }
2014 mouseClickQueue_.pop();
2015 mouseClickQueue_.push(clickInfo);
2016 return false;
2017 }
2018
SendDoubleClickEvent(const MouseClickInfo & info)2019 void WebPattern::SendDoubleClickEvent(const MouseClickInfo& info)
2020 {
2021 CHECK_NULL_VOID(delegate_);
2022 delegate_->OnMouseEvent(info.x, info.y, MouseButton::LEFT_BUTTON, MouseAction::PRESS, DOUBLE_CLICK_NUM);
2023 }
2024
GenerateDragDropInfo(NG::DragDropInfo & dragDropInfo)2025 bool WebPattern::GenerateDragDropInfo(NG::DragDropInfo& dragDropInfo)
2026 {
2027 if (delegate_) {
2028 dragDropInfo.pixelMap = delegate_->GetDragPixelMap();
2029 }
2030
2031 if (dragDropInfo.pixelMap) {
2032 isW3cDragEvent_ = true;
2033 return true;
2034 }
2035
2036 return false;
2037 }
2038
HandleOnDragStart(const RefPtr<OHOS::Ace::DragEvent> & info)2039 NG::DragDropInfo WebPattern::HandleOnDragStart(const RefPtr<OHOS::Ace::DragEvent>& info)
2040 {
2041 if (snapshotImageNodeId_.has_value()) {
2042 TAG_LOGD(AceLogTag::ACE_WEB, "blankless during snapshot image, no need to handle on drag start!");
2043 return NG::DragDropInfo();
2044 }
2045 isDragging_ = true;
2046 isReceivedArkDrag_ = true;
2047 isDragStartFromWeb_ = true;
2048 NG::DragDropInfo dragDropInfo;
2049 if (GenerateDragDropInfo(dragDropInfo)) {
2050 auto frameNode = GetHost();
2051 CHECK_NULL_RETURN(frameNode, dragDropInfo);
2052 CHECK_NULL_RETURN(delegate_, dragDropInfo);
2053 CHECK_NULL_RETURN(delegate_->dragData_, dragDropInfo);
2054 // get drag pixel map successfully, disable next drag util received web kernel drag callback
2055 frameNode->SetDraggable(false);
2056 RefPtr<UnifiedData> aceUnifiedData = UdmfClient::GetInstance()->CreateUnifiedData();
2057 std::string fileName = delegate_->dragData_->GetImageFileName();
2058 std::string plainContent = delegate_->dragData_->GetFragmentText();
2059 std::string htmlContent = delegate_->dragData_->GetFragmentHtml();
2060 std::string linkUrl = delegate_->dragData_->GetLinkURL();
2061 std::string linkTitle = delegate_->dragData_->GetLinkTitle();
2062 if (!fileName.empty()) {
2063 OnDragFileNameStart(aceUnifiedData, fileName);
2064 } else {
2065 TAG_LOGW(AceLogTag::ACE_WEB, "DragDrop event start, dragdata has no image file uri, just pass");
2066 }
2067 if (!plainContent.empty()) {
2068 isDragEndMenuShow_ = true;
2069 UdmfClient::GetInstance()->AddPlainTextRecord(aceUnifiedData, plainContent);
2070 }
2071 if (!htmlContent.empty()) {
2072 isDragEndMenuShow_ = true;
2073 UdmfClient::GetInstance()->AddHtmlRecord(aceUnifiedData, htmlContent, "");
2074 }
2075 if (!linkUrl.empty()) {
2076 isDragEndMenuShow_ = false;
2077 UdmfClient::GetInstance()->AddLinkRecord(aceUnifiedData, linkUrl, linkTitle);
2078 TAG_LOGI(AceLogTag::ACE_WEB, "web DragDrop event Start, linkUrl size:%{public}zu", linkUrl.size());
2079 }
2080 UdmfClient::GetInstance()->SetTagProperty(aceUnifiedData, "records_to_entries_data_format");
2081 info->SetData(aceUnifiedData);
2082 HandleOnDragEnter(info);
2083 return dragDropInfo;
2084 }
2085 return dragDropInfo;
2086 }
2087
OnDragFileNameStart(const RefPtr<UnifiedData> & aceUnifiedData,const std::string & fileName)2088 void WebPattern::OnDragFileNameStart(const RefPtr<UnifiedData>& aceUnifiedData, const std::string& fileName)
2089 {
2090 isDragEndMenuShow_ = false;
2091 std::string fullName;
2092 if (delegate_->tempDir_.empty()) {
2093 fullName = "/data/storage/el2/base/haps/entry/temp/dragdrop/" + fileName;
2094 } else {
2095 fullName = delegate_->tempDir_ + "/dragdrop/" + fileName;
2096 }
2097 AppFileService::ModuleFileUri::FileUri fileUri(fullName);
2098 TAG_LOGI(AceLogTag::ACE_WEB, "web DragDrop event Start, FileUri:%{public}s, image path:%{public}s",
2099 fileUri.ToString().c_str(), fullName.c_str());
2100 std::vector<std::string> urlVec;
2101 std::string udmfUri = fileUri.ToString();
2102 urlVec.emplace_back(udmfUri);
2103 UdmfClient::GetInstance()->AddFileUriRecord(aceUnifiedData, urlVec);
2104 }
2105
HandleOnDropMove(const RefPtr<OHOS::Ace::DragEvent> & info)2106 void WebPattern::HandleOnDropMove(const RefPtr<OHOS::Ace::DragEvent>& info)
2107 {
2108 if (snapshotImageNodeId_.has_value()) {
2109 TAG_LOGD(AceLogTag::ACE_WEB, "blankless during snapshot image, no need to handle on drag move!");
2110 return;
2111 }
2112 if (!isDragging_) {
2113 return;
2114 }
2115
2116 if (!isW3cDragEvent_) {
2117 return;
2118 }
2119
2120 CHECK_NULL_VOID(delegate_);
2121 auto host = GetHost();
2122 CHECK_NULL_VOID(host);
2123 auto pipelineContext = host->GetContextRefPtr();
2124 CHECK_NULL_VOID(pipelineContext);
2125 auto viewScale = pipelineContext->GetViewScale();
2126 int32_t globalX = static_cast<int32_t>(info->GetX()) * viewScale;
2127 int32_t globalY = static_cast<int32_t>(info->GetY()) * viewScale;
2128 auto offset = GetCoordinatePoint();
2129 globalX = static_cast<int32_t>(globalX - offset.value_or(OffsetF()).GetX());
2130 globalY = static_cast<int32_t>(globalY - offset.value_or(OffsetF()).GetY());
2131 delegate_->HandleDragEvent(globalX, globalY, DragAction::DRAG_OVER);
2132 }
2133
InitCommonDragDropEvent(const RefPtr<GestureEventHub> & gestureHub)2134 void WebPattern::InitCommonDragDropEvent(const RefPtr<GestureEventHub>& gestureHub)
2135 {
2136 auto frameNode = GetHost();
2137 CHECK_NULL_VOID(frameNode);
2138 auto eventHub = frameNode->GetOrCreateEventHub<WebEventHub>();
2139 CHECK_NULL_VOID(eventHub);
2140
2141 isDisableDrag_ = false;
2142 // disable drag
2143 frameNode->SetDraggable(false);
2144 // init common drag drop event
2145 gestureHub->InitDragDropEvent();
2146 InitWebEventHubDragDropStart(eventHub);
2147 InitWebEventHubDragDropEnd(eventHub);
2148 InitWebEventHubDragMove(eventHub);
2149 TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop WebEventHub init drag event ok");
2150 }
2151
InitWebEventHubDragDropStart(const RefPtr<WebEventHub> & eventHub)2152 void WebPattern::InitWebEventHubDragDropStart(const RefPtr<WebEventHub>& eventHub)
2153 {
2154 auto onDragStartId = [weak = WeakClaim(this)](const RefPtr<OHOS::Ace::DragEvent>& info,
2155 const std::string& extraParams) -> NG::DragDropInfo {
2156 TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop WebEventHub drag start,"
2157 " x:%{public}lf, y:%{public}lf", info->GetX(), info->GetY());
2158 NG::DragDropInfo dragDropInfo;
2159 auto pattern = weak.Upgrade();
2160 if (pattern) {
2161 TAG_LOGI(AceLogTag::ACE_WEB,
2162 "DragDrop event WebEventHub onDragStartId, x:%{public}lf, y:%{public}lf, webId:%{public}d",
2163 info->GetX(), info->GetY(), pattern->GetWebId());
2164 pattern->dropX_ = 0;
2165 pattern->dropY_ = 0;
2166 return pattern->HandleOnDragStart(info);
2167 }
2168 return dragDropInfo;
2169 };
2170
2171 auto onDragEnterId = [weak = WeakClaim(this)](const RefPtr<OHOS::Ace::DragEvent>& info,
2172 const std::string& extraParams) {
2173 TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop WebEventHub drag enter,"
2174 " x:%{public}lf, y:%{public}lf", info->GetX(), info->GetY());
2175 auto pattern = weak.Upgrade();
2176 CHECK_NULL_VOID(pattern);
2177 TAG_LOGI(AceLogTag::ACE_WEB,
2178 "DragDrop event WebEventHub onDragEnterId, x:%{public}lf, y:%{public}lf, webId:%{public}d",
2179 info->GetX(), info->GetY(), pattern->GetWebId());
2180 pattern->isW3cDragEvent_ = true;
2181 pattern->isDragging_ = true;
2182 pattern->isReceivedArkDrag_ = true;
2183 pattern->dropX_ = 0;
2184 pattern->dropY_ = 0;
2185 return pattern->HandleOnDragEnter(info);
2186 };
2187
2188 // set custom OnDragStart function
2189 eventHub->SetOnDragStart(std::move(onDragStartId));
2190 eventHub->SetOnDragEnter(std::move(onDragEnterId));
2191 }
2192
InitWebEventHubDragMove(const RefPtr<WebEventHub> & eventHub)2193 void WebPattern::InitWebEventHubDragMove(const RefPtr<WebEventHub>& eventHub)
2194 {
2195 auto onDragMoveId = [weak = WeakClaim(this)](const RefPtr<OHOS::Ace::DragEvent>& info,
2196 const std::string& extraParams) {
2197 static uint32_t dragMoveCnt = 0;
2198 if ((dragMoveCnt % DEBUG_DRAGMOVEID_TIMER) == 0) {
2199 TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop WebEventHub drag move,"
2200 " x:%{public}lf, y:%{public}lf", info->GetX(), info->GetY());
2201 }
2202 auto pattern = weak.Upgrade();
2203 CHECK_NULL_VOID(pattern);
2204 if ((dragMoveCnt++ % DEBUG_DRAGMOVEID_TIMER) == 0) {
2205 TAG_LOGI(AceLogTag::ACE_WEB,
2206 "DragDrop event WebEventHub onDragMoveId, x:%{public}lf, y:%{public}lf, webId:%{public}d",
2207 info->GetX(), info->GetY(), pattern->GetWebId());
2208 }
2209 if (!pattern->isDragging_) {
2210 return;
2211 }
2212
2213 // update drag status
2214 info->SetResult(pattern->GetDragAcceptableStatus());
2215
2216 pattern->HandleOnDropMove(info);
2217 };
2218 // set custom OnDragStart function
2219 eventHub->SetOnDragMove(std::move(onDragMoveId));
2220 }
2221
InitWebEventHubDragDropEnd(const RefPtr<WebEventHub> & eventHub)2222 void WebPattern::InitWebEventHubDragDropEnd(const RefPtr<WebEventHub>& eventHub)
2223 {
2224 auto onDragDropId = [weak = WeakClaim(this)](const RefPtr<OHOS::Ace::DragEvent>& info,
2225 const std::string& extraParams) {
2226 TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop WebEventHub drag drop,"
2227 " x:%{public}lf, y:%{public}lf", info->GetX(), info->GetY());
2228 auto pattern = weak.Upgrade();
2229 CHECK_NULL_VOID(pattern);
2230 TAG_LOGI(AceLogTag::ACE_WEB,
2231 "DragDrop event WebEventHub onDragDropId, x:%{public}lf, y:%{public}lf, webId:%{public}d",
2232 info->GetX(), info->GetY(), pattern->GetWebId());
2233 if (!pattern->isDragging_) {
2234 return;
2235 }
2236 pattern->dropX_ = info->GetX();
2237 pattern->dropY_ = info->GetY();
2238 pattern->HandleOnDragDrop(info);
2239 };
2240
2241 auto onDragLeaveId = [weak = WeakClaim(this)](const RefPtr<OHOS::Ace::DragEvent>& info,
2242 const std::string& extraParams) {
2243 TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop WebEventHub drag leave,"
2244 " x:%{public}lf, y:%{public}lf", info->GetX(), info->GetY());
2245 auto pattern = weak.Upgrade();
2246 CHECK_NULL_VOID(pattern);
2247 TAG_LOGI(AceLogTag::ACE_WEB,
2248 "DragDrop event WebEventHub onDragLeaveId, x:%{public}lf, y:%{public}lf, webId:%{public}d",
2249 info->GetX(), info->GetY(), pattern->GetWebId());
2250 pattern->HandleOnDragLeave(info->GetX(), info->GetY());
2251 };
2252
2253 auto onDragEndId = [weak = WeakClaim(this)](const RefPtr<OHOS::Ace::DragEvent>& info) {
2254 TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop WebEventHub drag end,"
2255 " x:%{public}lf, y:%{public}lf", info->GetX(), info->GetY());
2256 auto pattern = weak.Upgrade();
2257 CHECK_NULL_VOID(pattern);
2258 TAG_LOGI(AceLogTag::ACE_WEB,
2259 "DragDrop event WebEventHub onDragEndId, x:%{public}lf, y:%{public}lf, webId:%{public}d",
2260 info->GetX(), info->GetY(), pattern->GetWebId());
2261 pattern->HandleDragEnd(pattern->dropX_, pattern->dropY_);
2262 };
2263 // set custom OnDragStart function
2264 eventHub->SetOnDragEnd(std::move(onDragEndId));
2265 eventHub->SetOnDragLeave(std::move(onDragLeaveId));
2266 eventHub->SetOnDrop(std::move(onDragDropId));
2267 }
2268
IsImageDrag()2269 bool WebPattern::IsImageDrag()
2270 {
2271 if (delegate_) {
2272 return delegate_->IsImageDrag();
2273 }
2274 return false;
2275 }
2276
GetDragAcceptableStatus()2277 DragRet WebPattern::GetDragAcceptableStatus()
2278 {
2279 OHOS::NWeb::NWebDragData::DragOperation status = delegate_->GetDragAcceptableStatus();
2280 int newDragOperation = static_cast<int>(status);
2281 // Fixed the issue that the corner icon blinks when you enter the move text box.
2282 if (lastDragOperation_ != newDragOperation) {
2283 lastDragOperation_ = newDragOperation;
2284 return DragRet::DRAG_DEFAULT;
2285 }
2286 if (status == OHOS::NWeb::NWebDragData::DragOperation::DRAG_OPERATION_COPY ||
2287 status == OHOS::NWeb::NWebDragData::DragOperation::DRAG_OPERATION_LINK) {
2288 return DragRet::ENABLE_DROP;
2289 } else if (status == OHOS::NWeb::NWebDragData::DragOperation::DRAG_OPERATION_MOVE) {
2290 return DragRet::DRAG_DEFAULT;
2291 }
2292 return DragRet::DISABLE_DROP;
2293 }
2294
NotifyStartDragTask(bool isDelayed)2295 bool WebPattern::NotifyStartDragTask(bool isDelayed)
2296 {
2297 if (isDisableDrag_ || isTouchUpEvent_) {
2298 TAG_LOGW(AceLogTag::ACE_WEB, "DragDrop disable drag in web. isDisableDrag_:%{public}d,"
2299 "isTouchUpEvent_:%{public}d, isDelayed:%{public}d", isDisableDrag_, isTouchUpEvent_, isDelayed);
2300 if (isDelayed) {
2301 CHECK_NULL_RETURN(delegate_, false);
2302 delegate_->HandleDragEvent(0, 0, DragAction::DRAG_CANCEL);
2303 }
2304 return false;
2305 }
2306 auto pipeline = PipelineContext::GetCurrentContext();
2307 CHECK_NULL_RETURN(pipeline, false);
2308 CHECK_NULL_RETURN(delegate_, false);
2309 auto manager = pipeline->GetDragDropManager();
2310 if (!manager || manager->IsDragging() || manager->IsMSDPDragging()) {
2311 TAG_LOGW(AceLogTag::ACE_WEB, "DragDrop, It's already dragging now, can't start drag task.");
2312 delegate_->HandleDragEvent(0, 0, DragAction::DRAG_CANCEL);
2313 return false;
2314 }
2315 isDragging_ = true;
2316 auto frameNode = GetHost();
2317 CHECK_NULL_RETURN(frameNode, false);
2318 auto eventHub = frameNode->GetOrCreateEventHub<WebEventHub>();
2319 CHECK_NULL_RETURN(eventHub, false);
2320 auto gestureHub = eventHub->GetOrCreateGestureEventHub();
2321 CHECK_NULL_RETURN(gestureHub, false);
2322 if (curContextMenuResult_ && (!(isNewDragStyle_ || isAILinkMenuShow_) || !previewImageNodeId_.has_value())) {
2323 TAG_LOGI(AceLogTag::ACE_WEB,
2324 "preview menu is not displayed, and the app is notified to close the long-press menu");
2325 delegate_->OnContextMenuHide("");
2326 }
2327 // received web kernel drag callback, enable drag
2328 frameNode->SetDraggable(true);
2329 gestureHub->SetPixelMap(delegate_->GetDragPixelMap());
2330 if (!IsPreviewImageNodeExist()) {
2331 StartVibraFeedback("longPress.light");
2332 }
2333 if (!isMouseEvent_) {
2334 // mouse drag does not need long press action
2335 gestureHub->StartLongPressActionForWeb();
2336 }
2337 TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop enable drag and start drag task for web,"
2338 "is mouse event: %{public}d", isMouseEvent_);
2339 bool result = gestureHub->StartDragTaskForWeb();
2340 if (!result && isMouseEvent_) {
2341 TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop start drag task for web fail, reset drag action");
2342 ResetDragAction();
2343 }
2344 return true;
2345 }
2346
InitDragEvent(const RefPtr<GestureEventHub> & gestureHub)2347 void WebPattern::InitDragEvent(const RefPtr<GestureEventHub>& gestureHub)
2348 {
2349 if (dragEvent_) {
2350 return;
2351 }
2352
2353 auto host = GetHost();
2354 CHECK_NULL_VOID(host);
2355 auto eventHub = host->GetOrCreateEventHub<WebEventHub>();
2356 CHECK_NULL_VOID(eventHub);
2357
2358 auto userOnDragStartFunc = eventHub->GetOnDragStart();
2359 if (userOnDragStartFunc) {
2360 isDisableDrag_ = true;
2361 return;
2362 }
2363
2364 InitCommonDragDropEvent(gestureHub);
2365
2366 auto actionStartTask = [weak = WeakClaim(this)](const GestureEvent& info) {
2367 int32_t x = info.GetGlobalPoint().GetX();
2368 int32_t y = info.GetGlobalPoint().GetY();
2369 auto pattern = weak.Upgrade();
2370 CHECK_NULL_VOID(pattern);
2371 TAG_LOGI(AceLogTag::ACE_WEB,
2372 "DragDrop event gestureHub actionStartTask x:%{public}d, y:%{public}d, webId:%{public}d",
2373 x, y, pattern->GetWebId());
2374 pattern->HandleDragStart(x, y);
2375 };
2376
2377 auto actionUpdateTask = [weak = WeakClaim(this)](const GestureEvent& info) {
2378 return;
2379 };
2380
2381 auto actionEndTask = [weak = WeakClaim(this)](const GestureEvent& info) {
2382 int32_t x = info.GetGlobalPoint().GetX();
2383 int32_t y = info.GetGlobalPoint().GetY();
2384 auto pattern = weak.Upgrade();
2385 CHECK_NULL_VOID(pattern);
2386 TAG_LOGI(AceLogTag::ACE_WEB,
2387 "DragDrop event gestureHub actionEndTask x:%{public}d, y:%{public}d, webId:%{public}d",
2388 x, y, pattern->GetWebId());
2389 pattern->HandleDragEnd(x, y);
2390 };
2391
2392 auto actionCancelTask = [weak = WeakClaim(this)]() {
2393 auto pattern = weak.Upgrade();
2394 CHECK_NULL_VOID(pattern);
2395 TAG_LOGI(AceLogTag::ACE_WEB,
2396 "DragDrop event gestureHub actionCancelTask webId:%{public}d", pattern->GetWebId());
2397 pattern->HandleDragCancel();
2398 };
2399
2400 dragEvent_ = MakeRefPtr<DragEvent>(
2401 std::move(actionStartTask), std::move(actionUpdateTask), std::move(actionEndTask), std::move(actionCancelTask));
2402 gestureHub->SetCustomDragEvent(dragEvent_, { PanDirection::ALL }, DEFAULT_PAN_FINGER, DEFAULT_PAN_DISTANCE);
2403 gestureHub->SetRecognizerDelayStatus(RecognizerDelayStatus::NONE);
2404 TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop, init drag event done, isReceivedArkDrag_ is %{public}d",
2405 (int)isReceivedArkDrag_);
2406 }
2407
HandleDragStart(int32_t x,int32_t y)2408 void WebPattern::HandleDragStart(int32_t x, int32_t y)
2409 {
2410 if (snapshotImageNodeId_.has_value()) {
2411 TAG_LOGD(AceLogTag::ACE_WEB, "blankless during snapshot image, no need to handle drag start!");
2412 return;
2413 }
2414 TAG_LOGI(AceLogTag::ACE_WEB,
2415 "HandleDragStart DragDrop event actionStart, isDragStartFromWeb_:%{public}d, isMouseEvent_:%{public}d",
2416 (int)isDragStartFromWeb_, (int)isMouseEvent_);
2417 if (!isDragStartFromWeb_ && !isMouseEvent_) {
2418 auto frameNode = GetHost();
2419 CHECK_NULL_VOID(frameNode);
2420 frameNode->SetDraggable(false);
2421 auto eventHub = frameNode->GetOrCreateEventHub<WebEventHub>();
2422 CHECK_NULL_VOID(eventHub);
2423 auto gestureHub = eventHub->GetOrCreateGestureEventHub();
2424 CHECK_NULL_VOID(gestureHub);
2425 gestureHub->ResetDragActionForWeb();
2426 isDragging_ = false;
2427 isReceivedArkDrag_ = false;
2428 // cancel drag action to avoid web kernel can't process other input event
2429 CHECK_NULL_VOID(delegate_);
2430 delegate_->HandleDragEvent(0, 0, DragAction::DRAG_CANCEL);
2431 gestureHub->CancelDragForWeb();
2432 }
2433 if (!isDragStartFromWeb_ && isMouseEvent_) {
2434 auto frameNode = GetHost();
2435 CHECK_NULL_VOID(frameNode);
2436 auto eventHub = frameNode->GetOrCreateEventHub<WebEventHub>();
2437 CHECK_NULL_VOID(eventHub);
2438 auto gestureHub = eventHub->GetOrCreateGestureEventHub();
2439 CHECK_NULL_VOID(gestureHub);
2440 gestureHub->SetMouseDragMonitorState(true);
2441 isSetMouseDragMonitorState = true;
2442 }
2443 }
2444
HandleOnDragEnter(const RefPtr<OHOS::Ace::DragEvent> & info)2445 void WebPattern::HandleOnDragEnter(const RefPtr<OHOS::Ace::DragEvent>& info)
2446 {
2447 if (snapshotImageNodeId_.has_value()) {
2448 TAG_LOGD(AceLogTag::ACE_WEB, "blankless during snapshot image, no need to handle on drag enter!");
2449 return;
2450 }
2451 if (!delegate_) {
2452 return;
2453 }
2454
2455 auto host = GetHost();
2456 CHECK_NULL_VOID(host);
2457 auto pipelineContext = host->GetContextRefPtr();
2458 CHECK_NULL_VOID(pipelineContext);
2459 int32_t globalX = static_cast<int32_t>(info->GetX());
2460 int32_t globalY = static_cast<int32_t>(info->GetY());
2461 auto viewScale = pipelineContext->GetViewScale();
2462 auto offset = GetCoordinatePoint();
2463 int32_t localX = static_cast<int32_t>(globalX - offset.value_or(OffsetF()).GetX()) * viewScale;
2464 int32_t localY = static_cast<int32_t>(globalY - offset.value_or(OffsetF()).GetY()) * viewScale;
2465
2466 // fake drag data when enter
2467 delegate_->GetOrCreateDragData();
2468 // use summary to set fake data
2469 if (!isDragStartFromWeb_) {
2470 ClearDragData();
2471 SetFakeDragData(info);
2472 }
2473 delegate_->HandleDragEvent(localX, localY, DragAction::DRAG_ENTER);
2474 // RequestFocus to show the carret frame_caret
2475 WebRequestFocus();
2476 }
2477
HandleOnDragDropLink(RefPtr<UnifiedData> aceData)2478 void WebPattern::HandleOnDragDropLink(RefPtr<UnifiedData> aceData)
2479 {
2480 CHECK_NULL_VOID(aceData);
2481 CHECK_NULL_VOID(delegate_);
2482 CHECK_NULL_VOID(delegate_->dragData_);
2483 // hyperlink
2484 std::string linkUrl;
2485 std::string linkTitle;
2486 UdmfClient::GetInstance()->GetLinkEntry(aceData, linkUrl, linkTitle);
2487 if (!linkUrl.empty()) {
2488 delegate_->dragData_->SetLinkURL(linkUrl);
2489 delegate_->dragData_->SetLinkTitle(linkTitle);
2490 TAG_LOGI(AceLogTag::ACE_WEB,
2491 "DragDrop event WebEventHub onDragDropId, linkUrl size:%{public}zu", linkUrl.size());
2492 } else {
2493 TAG_LOGW(AceLogTag::ACE_WEB,
2494 "DragDrop event WebEventHub onDragDropId, linkUrl is empty");
2495 }
2496 }
2497
HandleOnDragDropFile(RefPtr<UnifiedData> aceData)2498 void WebPattern::HandleOnDragDropFile(RefPtr<UnifiedData> aceData)
2499 {
2500 CHECK_NULL_VOID(aceData);
2501 CHECK_NULL_VOID(delegate_);
2502 CHECK_NULL_VOID(delegate_->dragData_);
2503 // file
2504 std::vector<std::string> urlVec;
2505 UdmfClient::GetInstance()->GetFileUriEntry(aceData, urlVec);
2506 TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop event WebEventHub onDragDropId,"
2507 "url array size is:%{public}zu", urlVec.size());
2508 delegate_->dragData_->ClearImageFileNames();
2509 for (std::string url : urlVec) {
2510 TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop event WebEventHub onDragDropId,"
2511 "url get from udmf:%{public}zu", url.length());
2512 AppFileService::ModuleFileUri::FileUri fileUri(url);
2513 TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop event WebEventHub onDragDropId,"
2514 "fileUri ToString:%{public}zu", fileUri.ToString().length());
2515 std::string uriRealPath = FileUriHelper::GetRealPath(url);
2516 if (uriRealPath.empty()) {
2517 TAG_LOGW(AceLogTag::ACE_WEB, "DragDrop event WebEventHub onDragDropId, url is empty ");
2518 continue;
2519 }
2520 int access_result = access(uriRealPath.c_str(), F_OK);
2521 if (access_result == 0) {
2522 TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop event WebEventHub onDragDropId,url real path:%{public}zu",
2523 uriRealPath.length());
2524 delegate_->dragData_->SetFileUri(uriRealPath);
2525 } else {
2526 TAG_LOGW(AceLogTag::ACE_WEB,
2527 "DragDrop event WebEventHub onDragDropId, url can't access, "
2528 "uriRealPath:%{public}zu, access_result:%{public}d",
2529 uriRealPath.length(), access_result);
2530 }
2531 }
2532 }
2533
ResetDragStateValue()2534 void WebPattern::ResetDragStateValue()
2535 {
2536 isDragging_ = false;
2537 isReceivedArkDrag_ = false;
2538 isW3cDragEvent_ = false;
2539 isDragStartFromWeb_ = false;
2540 }
2541
HandleOnDragDrop(const RefPtr<OHOS::Ace::DragEvent> & info)2542 void WebPattern::HandleOnDragDrop(const RefPtr<OHOS::Ace::DragEvent>& info)
2543 {
2544 if (snapshotImageNodeId_.has_value()) {
2545 return;
2546 }
2547 ResetDragStateValue();
2548 CHECK_NULL_VOID(delegate_);
2549 auto host = GetHost();
2550 CHECK_NULL_VOID(host);
2551 auto pipelineContext = host->GetContextRefPtr();
2552 CHECK_NULL_VOID(pipelineContext);
2553 auto viewScale = pipelineContext->GetViewScale();
2554 auto offset = GetCoordinatePoint();
2555 int32_t localX = static_cast<int32_t>(info->GetX() - offset.value_or(OffsetF()).GetX()) * viewScale;
2556 int32_t localY = static_cast<int32_t>(info->GetY() - offset.value_or(OffsetF()).GetY()) * viewScale;
2557 ClearDragData();
2558 RefPtr<UnifiedData> aceData = info->GetData();
2559 // get data from ace(from udmf), and send it to chromium
2560 if (aceData && aceData->GetSize() >= 1) {
2561 TAG_LOGI(AceLogTag::ACE_WEB,
2562 "DragDrop event WebEventHub onDragDropId, size:%{public}" PRId64 "", aceData->GetSize());
2563 CHECK_NULL_VOID(delegate_->dragData_);
2564 // plain text
2565 std::string plain = UdmfClient::GetInstance()->GetPlainTextEntry(aceData);
2566 if (!plain.empty()) {
2567 delegate_->dragData_->SetFragmentText(plain);
2568 TAG_LOGI(AceLogTag::ACE_WEB,
2569 "DragDrop event WebEventHub onDragDropId, plain size:%{public}zu", plain.size());
2570 }
2571 // html
2572 std::string htmlContent;
2573 std::string plainContent;
2574 UdmfClient::GetInstance()->GetHtmlEntry(aceData, htmlContent, plainContent);
2575 if (!htmlContent.empty()) {
2576 delegate_->dragData_->SetFragmentHtml(htmlContent);
2577 TAG_LOGI(AceLogTag::ACE_WEB,
2578 "DragDrop event WebEventHub onDragDropId, htmlContent size:%{public}zu", htmlContent.size());
2579 }
2580 // spanstring
2581 std::vector<uint8_t> spanString = UdmfClient::GetInstance()->GetSpanStringEntry(aceData);
2582 if (!spanString.empty()) {
2583 std::string htmlStr = OHOS::Ace::SpanToHtml::ToHtml(spanString);
2584 delegate_->dragData_->SetFragmentHtml(htmlStr);
2585 TAG_LOGI(AceLogTag::ACE_WEB,
2586 "DragDrop event WebEventHub onDragDropId, spanstring to html success, html size:%{public}zu",
2587 htmlStr.size());
2588 }
2589 // link
2590 HandleOnDragDropLink(aceData);
2591 // file
2592 HandleOnDragDropFile(aceData);
2593 } else {
2594 TAG_LOGW(AceLogTag::ACE_WEB, "DragDrop event WebEventHub onDragDropId get data failed");
2595 }
2596
2597 delegate_->HandleDragEvent(localX, localY, DragAction::DRAG_DROP);
2598 delegate_->RegisterWebWindowFocusChangedListener();
2599 }
2600
HandleOnDragLeave(int32_t x,int32_t y)2601 void WebPattern::HandleOnDragLeave(int32_t x, int32_t y)
2602 {
2603 if (snapshotImageNodeId_.has_value()) {
2604 TAG_LOGD(AceLogTag::ACE_WEB, "blankless during snapshot image, no need to handle on drag leave!");
2605 return;
2606 }
2607 CHECK_NULL_VOID(delegate_);
2608 TAG_LOGI(AceLogTag::ACE_WEB,
2609 "DragDrop, HandleOnDragLeave, isDragStartFromWeb_ %{public}d, isReceivedArkDrag_ %{public}d",
2610 (int)isDragStartFromWeb_, (int)isReceivedArkDrag_);
2611 isDragging_ = false;
2612 isW3cDragEvent_ = false;
2613 isReceivedArkDrag_ = isDragStartFromWeb_ ? isReceivedArkDrag_ : false;
2614 auto host = GetHost();
2615 CHECK_NULL_VOID(host);
2616 auto pipelineContext = host->GetContextRefPtr();
2617 CHECK_NULL_VOID(pipelineContext);
2618 auto viewScale = pipelineContext->GetViewScale();
2619 auto offset = GetCoordinatePoint();
2620 int32_t localX = static_cast<int32_t>(x - offset.value_or(OffsetF()).GetX());
2621 int32_t localY = static_cast<int32_t>(y - offset.value_or(OffsetF()).GetY());
2622 delegate_->HandleDragEvent(localX * viewScale, localY * viewScale, DragAction::DRAG_LEAVE);
2623 }
2624
HandleDragEnd(int32_t x,int32_t y)2625 void WebPattern::HandleDragEnd(int32_t x, int32_t y)
2626 {
2627 if (snapshotImageNodeId_.has_value()) {
2628 TAG_LOGD(AceLogTag::ACE_WEB, "blankless during snapshot image, no need to handle drag end!");
2629 return;
2630 }
2631 CHECK_NULL_VOID(delegate_);
2632
2633 isDragging_ = false;
2634 isReceivedArkDrag_ = false;
2635 isW3cDragEvent_ = false;
2636 isDragStartFromWeb_ = false;
2637 ClearDragData();
2638
2639 auto host = GetHost();
2640 CHECK_NULL_VOID(host);
2641 auto pipelineContext = host->GetContextRefPtr();
2642 CHECK_NULL_VOID(pipelineContext);
2643 auto viewScale = pipelineContext->GetViewScale();
2644 auto offset = GetCoordinatePoint();
2645 int32_t localX = static_cast<int32_t>(x - offset.value_or(OffsetF()).GetX()) * viewScale;
2646 int32_t localY = static_cast<int32_t>(y - offset.value_or(OffsetF()).GetY()) * viewScale;
2647 if (x == 0 && y == 0) {
2648 delegate_->HandleDragEvent(0, 0, DragAction::DRAG_END);
2649 } else {
2650 delegate_->HandleDragEvent(localX, localY, DragAction::DRAG_END);
2651 }
2652 if (isSetMouseDragMonitorState) {
2653 auto eventHub = host->GetOrCreateEventHub<WebEventHub>();
2654 CHECK_NULL_VOID(eventHub);
2655 auto gestureHub = eventHub->GetOrCreateGestureEventHub();
2656 CHECK_NULL_VOID(gestureHub);
2657 gestureHub->SetMouseDragMonitorState(false);
2658 isSetMouseDragMonitorState = false;
2659 }
2660 }
2661
HandleDragCancel()2662 void WebPattern::HandleDragCancel()
2663 {
2664 auto frameNode = GetHost();
2665 CHECK_NULL_VOID(frameNode);
2666 // disable drag
2667 frameNode->SetDraggable(false);
2668 CHECK_NULL_VOID(delegate_);
2669 isDragging_ = false;
2670 isReceivedArkDrag_ = false;
2671 isW3cDragEvent_ = false;
2672 isDragStartFromWeb_ = false;
2673 ClearDragData();
2674 delegate_->HandleDragEvent(0, 0, DragAction::DRAG_CANCEL);
2675 }
2676
ClearDragData()2677 void WebPattern::ClearDragData()
2678 {
2679 CHECK_NULL_VOID(delegate_);
2680 std::string plain = "";
2681 std::string htmlContent = "";
2682 std::string linkUrl = "";
2683 std::string linkTitle = "";
2684 if (delegate_->dragData_) {
2685 delegate_->dragData_->SetFragmentText(plain);
2686 delegate_->dragData_->SetFragmentHtml(htmlContent);
2687 delegate_->dragData_->SetLinkURL(linkUrl);
2688 delegate_->dragData_->SetLinkTitle(linkTitle);
2689 delegate_->dragData_->ClearImageFileNames();
2690 }
2691 }
2692
SetFakeDragData(const RefPtr<OHOS::Ace::DragEvent> & info)2693 void WebPattern::SetFakeDragData(const RefPtr<OHOS::Ace::DragEvent>& info)
2694 {
2695 CHECK_NULL_VOID(delegate_);
2696 CHECK_NULL_VOID(delegate_->dragData_);
2697 if (info && !info->GetSummary().empty()) {
2698 std::map<std::string, int64_t> dragDataSummary = info->GetSummary();
2699 TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop, set fake drag data by summary, summary size is %{public}zu",
2700 dragDataSummary.size());
2701 std::map<std::string, int64_t>::iterator iter;
2702 for (iter = dragDataSummary.begin(); iter != dragDataSummary.end(); iter++) {
2703 if (FILE_TYPE_SET.find(iter->first) != FILE_TYPE_SET.end()) {
2704 delegate_->dragData_->SetFileUri(FAKE_DRAG_DATA_VAL);
2705 } else if (DRAG_DATA_TYPE_TEXT == iter->first) {
2706 delegate_->dragData_->SetFragmentText(FAKE_DRAG_DATA_VAL);
2707 } else if (DRAG_DATA_TYPE_HTML == iter->first || DRAG_DATA_TYPE_APP_DEF == iter->first) {
2708 delegate_->dragData_->SetFragmentHtml(FAKE_DRAG_DATA_VAL);
2709 } else if (DRAG_DATA_TYPE_LINK == iter->first) {
2710 delegate_->dragData_->SetLinkURL(FAKE_LINK_VAL);
2711 delegate_->dragData_->SetLinkTitle(FAKE_LINK_VAL);
2712 }
2713 }
2714 return;
2715 }
2716 delegate_->dragData_->SetFragmentText(FAKE_DRAG_DATA_VAL);
2717 delegate_->dragData_->SetFragmentHtml(FAKE_DRAG_DATA_VAL);
2718 }
2719
InitFocusEvent(const RefPtr<FocusHub> & focusHub)2720 void WebPattern::InitFocusEvent(const RefPtr<FocusHub>& focusHub)
2721 {
2722 auto focusTask = [weak = WeakClaim(this)](FocusReason reason) {
2723 auto pattern = weak.Upgrade();
2724 CHECK_NULL_VOID(pattern);
2725 pattern->HandleFocusEvent();
2726 };
2727 focusHub->SetOnFocusInternal(focusTask);
2728
2729 auto blurTask = [weak = WeakClaim(this)](const BlurReason& blurReason) {
2730 auto pattern = weak.Upgrade();
2731 CHECK_NULL_VOID(pattern);
2732 pattern->HandleBlurEvent(blurReason);
2733 };
2734 focusHub->SetOnBlurReasonInternal(blurTask);
2735
2736 auto keyTask = [weak = WeakClaim(this)](const KeyEvent& keyEvent) -> bool {
2737 auto pattern = weak.Upgrade();
2738 CHECK_NULL_RETURN(pattern, false);
2739 return pattern->HandleKeyEvent(keyEvent);
2740 };
2741 focusHub->SetOnKeyEventInternal(keyTask);
2742 }
2743
HandleFocusEvent()2744 void WebPattern::HandleFocusEvent()
2745 {
2746 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::HandleFocusEvent webId:%{public}d, needOnFocus: %{public}d.", GetWebId(),
2747 needOnFocus_);
2748 CHECK_NULL_VOID(delegate_);
2749 isFocus_ = true;
2750 if (needOnFocus_) {
2751 delegate_->OnFocus();
2752 } else {
2753 delegate_->OnFocus(OHOS::NWeb::FocusReason::FOCUS_DEFAULT);
2754 needOnFocus_ = true;
2755 }
2756 }
2757
HandleBlurEvent(const BlurReason & blurReason)2758 void WebPattern::HandleBlurEvent(const BlurReason& blurReason)
2759 {
2760 TAG_LOGI(AceLogTag::ACE_WEB,
2761 "HandleBlurEvent webId:%{public}d, selectPopupMenuShowing: %{public}d, isDragStartFromWeb: %{public}d",
2762 GetWebId(), selectPopupMenuShowing_, isDragStartFromWeb_);
2763 CHECK_NULL_VOID(delegate_);
2764 isFocus_ = false;
2765
2766 if (isDragStartFromWeb_) {
2767 return;
2768 }
2769 if (!selectPopupMenuShowing_) {
2770 delegate_->SetBlurReason(static_cast<OHOS::NWeb::BlurReason>(blurReason));
2771 delegate_->OnBlur();
2772 }
2773 OnQuickMenuDismissed();
2774 CloseContextSelectionMenu();
2775 if (!isVisible_ && isActive_ && IsDialogNested()) {
2776 TAG_LOGI(AceLogTag::ACE_WEB, "HandleBlurEvent, dialog nested blur but invisible while active, set inactive.");
2777 SetActiveStatusInner(false);
2778 }
2779 HideMagnifier();
2780 EnableSecurityLayer(false);
2781 }
2782
HandleKeyEvent(const KeyEvent & keyEvent)2783 bool WebPattern::HandleKeyEvent(const KeyEvent& keyEvent)
2784 {
2785 bool ret = false;
2786
2787 auto host = GetHost();
2788 CHECK_NULL_RETURN(host, ret);
2789 auto eventHub = host->GetOrCreateEventHub<WebEventHub>();
2790 CHECK_NULL_RETURN(eventHub, ret);
2791
2792 KeyEventInfo info(keyEvent);
2793 auto keyEventCallback = eventHub->GetOnKeyEvent();
2794 if (keyEventCallback) {
2795 keyEventCallback(info);
2796 }
2797
2798 auto preKeyEventCallback = eventHub->GetOnPreKeyEvent();
2799 if (preKeyEventCallback) {
2800 ret = preKeyEventCallback(info);
2801 if (ret) {
2802 return ret;
2803 }
2804 }
2805
2806 ret = WebOnKeyEvent(keyEvent);
2807 return ret;
2808 }
2809
ClearKeyEventByKeyCode(int32_t keyCode)2810 void WebPattern::ClearKeyEventByKeyCode(int32_t keyCode)
2811 {
2812 auto keyEvent = webKeyEvent_.begin();
2813 for (; keyEvent != webKeyEvent_.end();) {
2814 if (static_cast<int32_t>(keyEvent->code) == keyCode) {
2815 keyEvent = webKeyEvent_.erase(keyEvent);
2816 } else {
2817 ++keyEvent;
2818 }
2819 }
2820
2821 if (webKeyEvent_.size() >= KEYEVENT_MAX_NUM) {
2822 webKeyEvent_.clear();
2823 TAG_LOGW(AceLogTag::ACE_WEB,
2824 "WebPattern::ClearKeyEventByKeyCode clear all keyevent.");
2825 } else {
2826 TAG_LOGW(AceLogTag::ACE_WEB,
2827 "WebPattern::ClearKeyEventByKeyCode clear all tab keyevent.");
2828 }
2829 }
2830
WebOnKeyEvent(const KeyEvent & keyEvent)2831 bool WebPattern::WebOnKeyEvent(const KeyEvent& keyEvent)
2832 {
2833 CHECK_NULL_RETURN(delegate_, false);
2834 if (webKeyEvent_.size() >= KEYEVENT_MAX_NUM) {
2835 ClearKeyEventByKeyCode(static_cast<int32_t>(KeyCode::KEY_TAB));
2836 }
2837 TAG_LOGD(AceLogTag::ACE_WEB,
2838 "WebPattern::WebOnKeyEvent keyEvent:%{public}s", keyEvent.ToString().c_str());
2839 webKeyEvent_.push_back(keyEvent);
2840 if (keyEvent.code == KeyCode::KEY_TAB && keyEvent.action == KeyAction::DOWN) {
2841 tabKeyEvent_ = keyEvent;
2842 }
2843 std::vector<int32_t> pressedCodes;
2844 for (auto pCode : keyEvent.pressedCodes) {
2845 pressedCodes.push_back(static_cast<int32_t>(pCode));
2846 }
2847 KeyCode code = keyEvent.code;
2848 auto item = g_numPadFunctionMap.find(code);
2849 if (!keyEvent.numLock && item != g_numPadFunctionMap.end()) {
2850 code = item->second;
2851 }
2852 std::shared_ptr<NWebKeyboardEventImpl> keyboardEvent =
2853 std::make_shared<NWebKeyboardEventImpl>(static_cast<int32_t>(code),
2854 static_cast<int32_t>(keyEvent.action),
2855 keyEvent.unicode,
2856 keyEvent.enableCapsLock,
2857 pressedCodes);
2858 return delegate_->SendKeyboardEvent(keyboardEvent);
2859 }
2860
KeyboardReDispatch(const std::shared_ptr<OHOS::NWeb::NWebKeyEvent> & event,bool isUsed)2861 void WebPattern::KeyboardReDispatch(
2862 const std::shared_ptr<OHOS::NWeb::NWebKeyEvent>& event, bool isUsed)
2863 {
2864 CHECK_NULL_VOID(event);
2865 auto container = Container::Current();
2866 CHECK_NULL_VOID(container);
2867 auto host = GetHost();
2868 CHECK_NULL_VOID(host);
2869 auto pipelineContext = host->GetContext();
2870 CHECK_NULL_VOID(pipelineContext);
2871 auto taskExecutor = pipelineContext->GetTaskExecutor();
2872 CHECK_NULL_VOID(taskExecutor);
2873 auto keyEvent = webKeyEvent_.rbegin();
2874 for (; keyEvent != webKeyEvent_.rend(); ++keyEvent) {
2875 if (static_cast<int32_t>(keyEvent->code) == event->GetKeyCode() &&
2876 static_cast<int32_t>(keyEvent->action) == event->GetAction()) {
2877 break;
2878 }
2879 }
2880 if (keyEvent == webKeyEvent_.rend()) {
2881 TAG_LOGW(AceLogTag::ACE_WEB, "KeyEvent is not find keycode");
2882 return;
2883 }
2884 if (!isUsed) {
2885 taskExecutor->PostTask([context = AceType::WeakClaim(pipelineContext),
2886 event = *keyEvent] () {
2887 auto pipelineContext = context.Upgrade();
2888 CHECK_NULL_VOID(pipelineContext);
2889 TAG_LOGD(AceLogTag::ACE_WEB, "WebPattern::KeyboardReDispatch");
2890 pipelineContext->ReDispatch(const_cast<KeyEvent&>(event));
2891 },
2892 TaskExecutor::TaskType::UI, "ArkUIWebKeyboardReDispatch");
2893 }
2894 TAG_LOGD(AceLogTag::ACE_WEB, "WebPattern::KeyboardReDispatch erase key");
2895 webKeyEvent_.erase((++keyEvent).base());
2896 }
2897
OnTakeFocus(const std::shared_ptr<OHOS::NWeb::NWebKeyEvent> & event)2898 void WebPattern::OnTakeFocus(const std::shared_ptr<OHOS::NWeb::NWebKeyEvent>& event)
2899 {
2900 CHECK_NULL_VOID(event);
2901 auto container = Container::Current();
2902 CHECK_NULL_VOID(container);
2903 auto host = GetHost();
2904 CHECK_NULL_VOID(host);
2905 auto pipelineContext = host->GetContext();
2906 CHECK_NULL_VOID(pipelineContext);
2907 auto taskExecutor = pipelineContext->GetTaskExecutor();
2908 CHECK_NULL_VOID(taskExecutor);
2909 if (static_cast<int32_t>(tabKeyEvent_.code) != event->GetKeyCode() ||
2910 static_cast<int32_t>(tabKeyEvent_.action) != event->GetAction()) {
2911 return;
2912 }
2913 taskExecutor->PostTask([context = AceType::WeakClaim(pipelineContext),
2914 event = tabKeyEvent_] () {
2915 auto pipelineContext = context.Upgrade();
2916 CHECK_NULL_VOID(pipelineContext);
2917 pipelineContext->ReDispatch(const_cast<KeyEvent&>(event));
2918 },
2919 TaskExecutor::TaskType::UI, "ArkUIWebKeyboardReDispatch");
2920 }
2921
WebRequestFocus()2922 void WebPattern::WebRequestFocus()
2923 {
2924 auto host = GetHost();
2925 CHECK_NULL_VOID(host);
2926 auto eventHub = host->GetOrCreateEventHub<WebEventHub>();
2927 CHECK_NULL_VOID(eventHub);
2928 auto focusHub = eventHub->GetOrCreateFocusHub();
2929 CHECK_NULL_VOID(focusHub);
2930
2931 focusHub->RequestFocusImmediately();
2932 }
2933
UpdateContentOffset(const RefPtr<LayoutWrapper> & dirty)2934 void WebPattern::UpdateContentOffset(const RefPtr<LayoutWrapper>& dirty)
2935 {
2936 CHECK_NULL_VOID(dirty);
2937 auto geometryNode = dirty->GetGeometryNode();
2938 CHECK_NULL_VOID(geometryNode);
2939 auto host = GetHost();
2940 CHECK_NULL_VOID(host);
2941 auto renderContext = host->GetRenderContext();
2942 CHECK_NULL_VOID(renderContext);
2943 auto paddingOffset = geometryNode->GetPaddingOffset();
2944 auto webContentSize = geometryNode->GetContentSize();
2945
2946 auto positionProperty = renderContext->GetPropertyOfPosition();
2947 renderContext->SetBounds(
2948 paddingOffset.GetX() + positionProperty.GetX(), paddingOffset.GetY() + positionProperty.GetY(),
2949 webContentSize.Width(), webContentSize.Height());
2950 }
2951
OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> & dirty,const DirtySwapConfig & config)2952 bool WebPattern::OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config)
2953 {
2954 UpdateImagePreviewParam();
2955 if (selectOverlayProxy_) {
2956 selectOverlayProxy_->UpdateAncestorViewPort(GetViewPort());
2957 }
2958 if (!config.contentSizeChange || isInWindowDrag_) {
2959 if (isLayoutModeChanged_) {
2960 isLayoutModeChanged_ = false;
2961 } else {
2962 return false;
2963 }
2964 }
2965 CHECK_NULL_RETURN(delegate_, false);
2966 CHECK_NULL_RETURN(dirty, false);
2967
2968 Size drawSize = Size(1, 1);
2969 auto frameNode = GetHost();
2970 CHECK_NULL_RETURN(frameNode, false);
2971 auto renderContext = frameNode->GetRenderContext();
2972 CHECK_NULL_RETURN(renderContext, false);
2973 auto rect = renderContext->GetPaintRectWithoutTransform();
2974 drawSize = Size(rect.Width(), rect.Height());
2975 if (drawSize.IsInfinite() || drawSize.IsEmpty()) {
2976 return false;
2977 }
2978
2979 if (GreatOrEqual(drawSize.Width(), Infinity<double>())) {
2980 drawSize.SetWidth(DEFAULT_WEB_WIDTH);
2981 }
2982 if (GreatOrEqual(drawSize.Height(), Infinity<double>())) {
2983 drawSize.SetHeight(DEFAULT_WEB_HEIGHT);
2984 }
2985
2986 drawSize_ = drawSize;
2987 drawSizeCache_ = drawSize_;
2988 if(!GetCoordinatePoint().has_value()) {
2989 return false;
2990 }
2991 auto offset = Offset(GetCoordinatePoint()->GetX(), GetCoordinatePoint()->GetY());
2992 if (!CheckSafeAreaIsExpand()) {
2993 TAG_LOGI(AceLogTag::ACE_WEB, "Not safe area, drawsize_ : %{public}s, web id : %{public}d",
2994 drawSize_.ToString().c_str(), GetWebId());
2995 ACE_SCOPED_TRACE("WebPattern::OnDirtyLayoutWrapperSwap, drawsize_ : %s, web id : %d",
2996 drawSize_.ToString().c_str(), GetWebId());
2997 if (isVirtualKeyBoardShow_ == VkState::VK_SHOW) {
2998 auto pipeline = PipelineContext::GetCurrentContext();
2999 CHECK_NULL_RETURN(pipeline, false);
3000 ProcessVirtualKeyBoard(pipeline->GetRootWidth(), pipeline->GetRootHeight(), lastKeyboardHeight_);
3001 }
3002 delegate_->SetBoundsOrResize(drawSize_, offset, isKeyboardInSafeArea_ || keyboardGetready_);
3003 IsNeedResizeVisibleViewport();
3004 isKeyboardInSafeArea_ = false;
3005 } else {
3006 TAG_LOGD(AceLogTag::ACE_WEB, "OnDirtyLayoutWrapperSwap safeArea is set, no need setbounds");
3007 }
3008 if (offlineWebInited_ && !offlineWebRendered_) {
3009 TAG_LOGI(AceLogTag::ACE_WEB,
3010 "OnDirtyLayoutWrapperSwap; WebPattern is Offline Mode, WebId:%{public}d", GetWebId());
3011 offlineWebRendered_ = true;
3012 SetActiveStatusInner(true);
3013 }
3014
3015 // first update size to load url.
3016 if (!isUrlLoaded_) {
3017 isUrlLoaded_ = true;
3018 if (webSrc_) {
3019 delegate_->LoadUrl();
3020 } else if (webData_) {
3021 delegate_->LoadDataWithRichText();
3022 }
3023 }
3024
3025 if (renderMode_ == RenderMode::SYNC_RENDER) {
3026 return true;
3027 }
3028 return false;
3029 }
3030
BeforeSyncGeometryProperties(const DirtySwapConfig & config)3031 void WebPattern::BeforeSyncGeometryProperties(const DirtySwapConfig& config)
3032 {
3033 auto frameNode = GetHost();
3034 CHECK_NULL_VOID(frameNode);
3035 auto renderContext = frameNode->GetRenderContext();
3036 CHECK_NULL_VOID(renderContext);
3037 auto rect = renderContext->GetPaintRectWithoutTransform();
3038 auto heightBeforeUpdate = rect.Height();
3039 if (isResizeContentAvoid_ && frameNode->SelfExpansive()) {
3040 rect.SetHeight(heightAfterAvoid_);
3041 renderContext->UpdatePaintRect(rect);
3042 rect.SetHeight(heightBeforeUpdate);
3043 }
3044
3045 if (!config.contentSizeChange || isInWindowDrag_) {
3046 return;
3047 }
3048 auto drawSize = Size(rect.Width(), rect.Height());
3049 if (drawSize.IsInfinite() || drawSize.IsEmpty()) {
3050 return;
3051 }
3052
3053 if (GreatOrEqual(drawSize.Width(), Infinity<double>())) {
3054 drawSize.SetWidth(DEFAULT_WEB_WIDTH);
3055 }
3056 if (GreatOrEqual(drawSize.Height(), Infinity<double>())) {
3057 drawSize.SetHeight(DEFAULT_WEB_HEIGHT);
3058 }
3059
3060 TAG_LOGD(AceLogTag::ACE_WEB, "BeforeSync, drawsize_ : %{public}s", drawSize.ToString().c_str());
3061 if (layoutMode_ != WebLayoutMode::FIT_CONTENT) {
3062 drawSize_ = drawSize;
3063 drawSizeCache_ = drawSize_;
3064 }
3065 }
3066
GetVisibleViewportAvoidHeight()3067 int32_t WebPattern::GetVisibleViewportAvoidHeight()
3068 {
3069 int32_t avoidHeight = 0;
3070 if (delegate_ != nullptr && delegate_->GetNweb() != nullptr) {
3071 avoidHeight = delegate_->GetNweb()->GetVisibleViewportAvoidHeight();
3072 }
3073 return avoidHeight;
3074 }
3075
UpdateLayoutAfterKeyboardShow(int32_t width,int32_t height,double keyboard,double oldWebHeight)3076 void WebPattern::UpdateLayoutAfterKeyboardShow(int32_t width, int32_t height, double keyboard, double oldWebHeight)
3077 {
3078 lastKeyboardHeight_ = keyboard;
3079 if (isVirtualKeyBoardShow_ != VkState::VK_SHOW) {
3080 return;
3081 }
3082
3083 TAG_LOGI(AceLogTag::ACE_WEB,
3084 "KeyboardShow height:%{public}d, keyboard:%{public}f, offset:%{public}f, oldWebHeight:%{public}f",
3085 height, keyboard, GetCoordinatePoint()->GetY(), oldWebHeight);
3086 if (CheckSafeAreaKeyBoard()) {
3087 TAG_LOGI(AceLogTag::ACE_WEB, "CheckSafeAreaKeyBoard, no need resize");
3088 return;
3089 }
3090 if (GreatOrEqual(height, keyboard + GetCoordinatePoint()->GetY())) {
3091 double newHeight = height - keyboard - GetCoordinatePoint()->GetY();
3092 if (NearEqual(newHeight, oldWebHeight)) {
3093 return;
3094 }
3095 bool isUpdate = true;
3096 if (GetVisibleViewportAvoidHeight() != 0) {
3097 TAG_LOGI(AceLogTag::ACE_WEB, "visible viewport avoid, behavior consistent with OVERLAYS_CONTENT");
3098 return;
3099 }
3100 if (keyBoardAvoidMode_ == WebKeyboardAvoidMode::RESIZE_VISUAL) {
3101 visibleViewportSize_.SetWidth(drawSize_.Width());
3102 visibleViewportSize_.SetHeight(newHeight);
3103 isUpdate = false;
3104 } else if (keyBoardAvoidMode_ == WebKeyboardAvoidMode::OVERLAYS_CONTENT) {
3105 return;
3106 } else {
3107 TAG_LOGI(AceLogTag::ACE_WEB, "KeyboardShow newHeight: %{public}f", newHeight);
3108 drawSize_.SetHeight(newHeight);
3109 visibleViewportSize_.SetWidth(-1.0);
3110 visibleViewportSize_.SetHeight(-1.0);
3111 isResizeContentAvoid_ = true;
3112 heightAfterAvoid_ = newHeight;
3113 }
3114 UpdateWebLayoutSize(width, height, true, isUpdate);
3115 }
3116 }
3117
OnAreaChangedInner()3118 void WebPattern::OnAreaChangedInner()
3119 {
3120 auto offset = GetCoordinatePoint().value_or(OffsetF());
3121 auto resizeOffset = Offset(offset.GetX(), offset.GetY());
3122
3123 auto frameNode = GetHost();
3124 CHECK_NULL_VOID(frameNode);
3125 auto renderContext = frameNode->GetRenderContext();
3126 CHECK_NULL_VOID(renderContext);
3127 auto geometryNode = frameNode->GetGeometryNode();
3128 CHECK_NULL_VOID(geometryNode);
3129 auto rect = renderContext->GetPaintRectWithoutTransform();
3130 auto size = Size(rect.Width(), rect.Height());
3131 delegate_->OnAreaChange({ resizeOffset.GetX(), resizeOffset.GetY(), size.Width(), size.Height() });
3132 if (CheckSafeAreaIsExpand() &&
3133 ((size.Width() != areaChangeSize_.Width()) || (size.Height() != areaChangeSize_.Height()))) {
3134 TAG_LOGD(AceLogTag::ACE_WEB, "OnAreaChangedInner setbounds: height:%{public}f, offsetY:%{public}f",
3135 size.Height(), resizeOffset.GetY());
3136 areaChangeSize_ = size;
3137 drawSize_ = size;
3138 if (renderMode_ != RenderMode::SYNC_RENDER) {
3139 drawSizeCache_ = drawSize_;
3140 }
3141 TAG_LOGD(AceLogTag::ACE_WEB, "Safe area, drawsize_ : %{public}s", drawSize_.ToString().c_str());
3142 delegate_->SetBoundsOrResize(drawSize_, resizeOffset, isKeyboardInSafeArea_);
3143 IsNeedResizeVisibleViewport();
3144 isKeyboardInSafeArea_ = false;
3145 }
3146 if (layoutMode_ == WebLayoutMode::NONE && renderMode_ == RenderMode::ASYNC_RENDER) {
3147 if (isVirtualKeyBoardShow_ != VkState::VK_SHOW) {
3148 drawSize_ = size;
3149 TAG_LOGD(AceLogTag::ACE_WEB, "ASYNC_RENDER, drawsize_ : %{public}s", drawSize_.ToString().c_str());
3150 }
3151 if (webOffset_ == offset) {
3152 return;
3153 }
3154 }
3155 if (offset != webOffset_) {
3156 webOffset_ = offset;
3157 if (webSelectOverlay_ && webSelectOverlay_->IsShowHandle())
3158 webSelectOverlay_->UpdateTouchHandleForOverlay();
3159 }
3160 if (isInWindowDrag_)
3161 return;
3162 TAG_LOGD(AceLogTag::ACE_WEB, "Normal state, drawsize_ : %{public}s", drawSize_.ToString().c_str());
3163 delegate_->SetBoundsOrResize(drawSize_, resizeOffset, isKeyboardInSafeArea_);
3164 IsNeedResizeVisibleViewport();
3165 isKeyboardInSafeArea_ = false;
3166 if (renderMode_ == RenderMode::SYNC_RENDER) {
3167 UpdateSlideOffset();
3168 }
3169 }
3170
OnWebSrcUpdate()3171 void WebPattern::OnWebSrcUpdate()
3172 {
3173 if (delegate_ && isUrlLoaded_) {
3174 delegate_->LoadUrl();
3175 }
3176 }
3177
OnWebDataUpdate()3178 void WebPattern::OnWebDataUpdate()
3179 {
3180 if (delegate_ && isUrlLoaded_) {
3181 delegate_->LoadDataWithRichText();
3182 }
3183 }
3184
OnJsEnabledUpdate(bool value)3185 void WebPattern::OnJsEnabledUpdate(bool value)
3186 {
3187 if (delegate_) {
3188 delegate_->UpdateJavaScriptEnabled(value);
3189 }
3190 }
3191
OnMediaPlayGestureAccessUpdate(bool value)3192 void WebPattern::OnMediaPlayGestureAccessUpdate(bool value)
3193 {
3194 if (delegate_) {
3195 delegate_->UpdateMediaPlayGestureAccess(value);
3196 }
3197 }
3198
OnFileAccessEnabledUpdate(bool value)3199 void WebPattern::OnFileAccessEnabledUpdate(bool value)
3200 {
3201 if (delegate_) {
3202 delegate_->UpdateAllowFileAccess(value);
3203 }
3204 }
3205
OnOnLineImageAccessEnabledUpdate(bool value)3206 void WebPattern::OnOnLineImageAccessEnabledUpdate(bool value)
3207 {
3208 if (delegate_) {
3209 delegate_->UpdateBlockNetworkImage(!value);
3210 }
3211 }
3212
OnDomStorageAccessEnabledUpdate(bool value)3213 void WebPattern::OnDomStorageAccessEnabledUpdate(bool value)
3214 {
3215 if (delegate_) {
3216 delegate_->UpdateDomStorageEnabled(value);
3217 }
3218 }
3219
OnImageAccessEnabledUpdate(bool value)3220 void WebPattern::OnImageAccessEnabledUpdate(bool value)
3221 {
3222 if (delegate_) {
3223 delegate_->UpdateLoadsImagesAutomatically(value);
3224 }
3225 }
3226
OnMixedModeUpdate(MixedModeContent value)3227 void WebPattern::OnMixedModeUpdate(MixedModeContent value)
3228 {
3229 if (delegate_) {
3230 delegate_->UpdateMixedContentMode(value);
3231 }
3232 }
3233
OnZoomAccessEnabledUpdate(bool value)3234 void WebPattern::OnZoomAccessEnabledUpdate(bool value)
3235 {
3236 if ((layoutMode_ == WebLayoutMode::FIT_CONTENT) || isEmbedModeEnabled_) {
3237 TAG_LOGI(AceLogTag::ACE_WEB, "When layoutMode is fit-content or EmbedMode is on, turn off zoom access.");
3238 value = false;
3239 }
3240 if (delegate_) {
3241 delegate_->UpdateSupportZoom(value);
3242 }
3243 }
3244
OnGeolocationAccessEnabledUpdate(bool value)3245 void WebPattern::OnGeolocationAccessEnabledUpdate(bool value)
3246 {
3247 if (delegate_) {
3248 delegate_->UpdateGeolocationEnabled(value);
3249 }
3250 }
3251
OnUserAgentUpdate(const std::string & value)3252 void WebPattern::OnUserAgentUpdate(const std::string& value)
3253 {
3254 if (delegate_) {
3255 delegate_->UpdateUserAgent(value);
3256 }
3257 }
3258
OnCacheModeUpdate(WebCacheMode value)3259 void WebPattern::OnCacheModeUpdate(WebCacheMode value)
3260 {
3261 if (delegate_) {
3262 delegate_->UpdateCacheMode(value);
3263 }
3264 }
3265
OnDarkModeUpdate(WebDarkMode mode)3266 void WebPattern::OnDarkModeUpdate(WebDarkMode mode)
3267 {
3268 if (delegate_) {
3269 delegate_->UpdateDarkMode(mode);
3270 }
3271 }
3272
OnOverScrollModeUpdate(int mode)3273 void WebPattern::OnOverScrollModeUpdate(int mode)
3274 {
3275 if (delegate_) {
3276 delegate_->UpdateOverScrollMode(mode);
3277 }
3278 }
3279
OnBlurOnKeyboardHideModeUpdate(int mode)3280 void WebPattern::OnBlurOnKeyboardHideModeUpdate(int mode)
3281 {
3282 if (delegate_) {
3283 delegate_->UpdateBlurOnKeyboardHideMode(mode);
3284 }
3285 }
3286
OnCopyOptionModeUpdate(int32_t mode)3287 void WebPattern::OnCopyOptionModeUpdate(int32_t mode)
3288 {
3289 if (delegate_) {
3290 delegate_->UpdateCopyOptionMode(mode);
3291 }
3292 }
3293
OnMetaViewportUpdate(bool value)3294 void WebPattern::OnMetaViewportUpdate(bool value)
3295 {
3296 if (delegate_) {
3297 delegate_->UpdateMetaViewport(value);
3298 }
3299 }
3300
OnForceDarkAccessUpdate(bool access)3301 void WebPattern::OnForceDarkAccessUpdate(bool access)
3302 {
3303 if (delegate_) {
3304 delegate_->UpdateForceDarkAccess(access);
3305 }
3306 }
3307
OnAudioResumeIntervalUpdate(int32_t resumeInterval)3308 void WebPattern::OnAudioResumeIntervalUpdate(int32_t resumeInterval)
3309 {
3310 if (delegate_) {
3311 delegate_->UpdateAudioResumeInterval(resumeInterval);
3312 }
3313 }
3314
OnAudioExclusiveUpdate(bool audioExclusive)3315 void WebPattern::OnAudioExclusiveUpdate(bool audioExclusive)
3316 {
3317 if (delegate_) {
3318 delegate_->UpdateAudioExclusive(audioExclusive);
3319 }
3320 }
3321
OnAudioSessionTypeUpdate(WebAudioSessionType value)3322 void WebPattern::OnAudioSessionTypeUpdate(WebAudioSessionType value)
3323 {
3324 if (delegate_) {
3325 delegate_->UpdateAudioSessionType(value);
3326 }
3327 }
3328
OnOverviewModeAccessEnabledUpdate(bool value)3329 void WebPattern::OnOverviewModeAccessEnabledUpdate(bool value)
3330 {
3331 if (delegate_) {
3332 delegate_->UpdateOverviewModeEnabled(value);
3333 }
3334 }
3335
OnFileFromUrlAccessEnabledUpdate(bool value)3336 void WebPattern::OnFileFromUrlAccessEnabledUpdate(bool value)
3337 {
3338 if (delegate_) {
3339 delegate_->UpdateFileFromUrlEnabled(value);
3340 }
3341 }
3342
OnDatabaseAccessEnabledUpdate(bool value)3343 void WebPattern::OnDatabaseAccessEnabledUpdate(bool value)
3344 {
3345 if (delegate_) {
3346 delegate_->UpdateDatabaseEnabled(value);
3347 }
3348 }
3349
OnTextZoomRatioUpdate(int32_t value)3350 void WebPattern::OnTextZoomRatioUpdate(int32_t value)
3351 {
3352 if (delegate_) {
3353 delegate_->UpdateTextZoomRatio(value);
3354 }
3355 }
3356
OnWebDebuggingAccessEnabledAndPortUpdate(const WebPatternProperty::WebDebuggingConfigType & enabled_and_port)3357 void WebPattern::OnWebDebuggingAccessEnabledAndPortUpdate(
3358 const WebPatternProperty::WebDebuggingConfigType& enabled_and_port)
3359 {
3360 if (delegate_) {
3361 bool enabled = std::get<0>(enabled_and_port);
3362 int32_t port = std::get<1>(enabled_and_port);
3363 if (port > 0) {
3364 delegate_->UpdateWebDebuggingAccessAndPort(enabled, port);
3365 } else {
3366 delegate_->UpdateWebDebuggingAccess(enabled);
3367 }
3368 }
3369 }
3370
OnPinchSmoothModeEnabledUpdate(bool value)3371 void WebPattern::OnPinchSmoothModeEnabledUpdate(bool value)
3372 {
3373 if (delegate_) {
3374 delegate_->UpdatePinchSmoothModeEnabled(value);
3375 }
3376 }
3377
OnBackgroundColorUpdate(int32_t value)3378 void WebPattern::OnBackgroundColorUpdate(int32_t value)
3379 {
3380 needSetDefaultBackgroundColor_ = false;
3381 UpdateBackgroundColorRightNow(value);
3382 if (delegate_) {
3383 delegate_->UpdateBackgroundColor(value);
3384 }
3385 }
3386
OnInitialScaleUpdate(float value)3387 void WebPattern::OnInitialScaleUpdate(float value)
3388 {
3389 if ((layoutMode_ == WebLayoutMode::FIT_CONTENT) || isEmbedModeEnabled_) {
3390 TAG_LOGI(AceLogTag::ACE_WEB, "When layoutMode is fit-content or EmbedMode is on, Not allow to update scale.");
3391 return;
3392 }
3393 if (delegate_) {
3394 delegate_->UpdateInitialScale(value);
3395 }
3396 }
3397
OnMultiWindowAccessEnabledUpdate(bool value)3398 void WebPattern::OnMultiWindowAccessEnabledUpdate(bool value)
3399 {
3400 if (delegate_) {
3401 delegate_->UpdateMultiWindowAccess(value);
3402 }
3403 }
3404
OnAllowWindowOpenMethodUpdate(bool value)3405 void WebPattern::OnAllowWindowOpenMethodUpdate(bool value)
3406 {
3407 if (delegate_) {
3408 delegate_->UpdateAllowWindowOpenMethod(value);
3409 }
3410 }
3411
OnWebCursiveFontUpdate(const std::string & value)3412 void WebPattern::OnWebCursiveFontUpdate(const std::string& value)
3413 {
3414 if (delegate_) {
3415 delegate_->UpdateWebCursiveFont(value);
3416 }
3417 }
3418
OnWebFantasyFontUpdate(const std::string & value)3419 void WebPattern::OnWebFantasyFontUpdate(const std::string& value)
3420 {
3421 if (delegate_) {
3422 delegate_->UpdateWebFantasyFont(value);
3423 }
3424 }
3425
OnWebFixedFontUpdate(const std::string & value)3426 void WebPattern::OnWebFixedFontUpdate(const std::string& value)
3427 {
3428 if (delegate_) {
3429 delegate_->UpdateWebFixedFont(value);
3430 }
3431 }
3432
OnWebSansSerifFontUpdate(const std::string & value)3433 void WebPattern::OnWebSansSerifFontUpdate(const std::string& value)
3434 {
3435 if (delegate_) {
3436 delegate_->UpdateWebSansSerifFont(value);
3437 }
3438 }
3439
OnWebSerifFontUpdate(const std::string & value)3440 void WebPattern::OnWebSerifFontUpdate(const std::string& value)
3441 {
3442 if (delegate_) {
3443 delegate_->UpdateWebSerifFont(value);
3444 }
3445 }
3446
OnWebStandardFontUpdate(const std::string & value)3447 void WebPattern::OnWebStandardFontUpdate(const std::string& value)
3448 {
3449 if (delegate_) {
3450 delegate_->UpdateWebStandardFont(value);
3451 }
3452 }
3453
OnDefaultFixedFontSizeUpdate(int32_t value)3454 void WebPattern::OnDefaultFixedFontSizeUpdate(int32_t value)
3455 {
3456 if (delegate_) {
3457 delegate_->UpdateDefaultFixedFontSize(value);
3458 }
3459 }
3460
OnDefaultFontSizeUpdate(int32_t value)3461 void WebPattern::OnDefaultFontSizeUpdate(int32_t value)
3462 {
3463 if (delegate_) {
3464 delegate_->UpdateDefaultFontSize(value);
3465 }
3466 }
3467
OnMinFontSizeUpdate(int32_t value)3468 void WebPattern::OnMinFontSizeUpdate(int32_t value)
3469 {
3470 if (delegate_) {
3471 delegate_->UpdateMinFontSize(value);
3472 }
3473 }
3474
OnMinLogicalFontSizeUpdate(int32_t value)3475 void WebPattern::OnMinLogicalFontSizeUpdate(int32_t value)
3476 {
3477 if (delegate_) {
3478 delegate_->UpdateMinLogicalFontSize(value);
3479 }
3480 }
3481
OnBlockNetworkUpdate(bool value)3482 void WebPattern::OnBlockNetworkUpdate(bool value)
3483 {
3484 if (delegate_) {
3485 delegate_->UpdateBlockNetwork(value);
3486 }
3487 }
3488
OnHorizontalScrollBarAccessEnabledUpdate(bool value)3489 void WebPattern::OnHorizontalScrollBarAccessEnabledUpdate(bool value)
3490 {
3491 if (delegate_) {
3492 delegate_->UpdateHorizontalScrollBarAccess(value);
3493 }
3494 }
3495
OnVerticalScrollBarAccessEnabledUpdate(bool value)3496 void WebPattern::OnVerticalScrollBarAccessEnabledUpdate(bool value)
3497 {
3498 if (delegate_) {
3499 delegate_->UpdateVerticalScrollBarAccess(value);
3500 }
3501 }
3502
OnOverlayScrollbarEnabledUpdate(bool enable)3503 void WebPattern::OnOverlayScrollbarEnabledUpdate(bool enable)
3504 {
3505 if (delegate_) {
3506 delegate_->UpdateOverlayScrollbarEnabled(enable);
3507 }
3508 }
3509
OnNativeEmbedModeEnabledUpdate(bool value)3510 void WebPattern::OnNativeEmbedModeEnabledUpdate(bool value)
3511 {
3512 if (delegate_) {
3513 delegate_->UpdateNativeEmbedModeEnabled(value);
3514 }
3515 }
3516
OnIntrinsicSizeEnabledUpdate(bool value)3517 void WebPattern::OnIntrinsicSizeEnabledUpdate(bool value)
3518 {
3519 if (delegate_) {
3520 delegate_->UpdateIntrinsicSizeEnabled(value);
3521 }
3522 }
3523
OnCssDisplayChangeEnabledUpdate(bool value)3524 void WebPattern::OnCssDisplayChangeEnabledUpdate(bool value)
3525 {
3526 if (delegate_) {
3527 delegate_->UpdateCssDisplayChangeEnabled(value);
3528 }
3529 }
3530
OnNativeEmbedRuleTagUpdate(const std::string & tag)3531 void WebPattern::OnNativeEmbedRuleTagUpdate(const std::string& tag)
3532 {
3533 if (delegate_) {
3534 delegate_->UpdateNativeEmbedRuleTag(tag);
3535 }
3536 }
3537
OnNativeEmbedRuleTypeUpdate(const std::string & type)3538 void WebPattern::OnNativeEmbedRuleTypeUpdate(const std::string& type)
3539 {
3540 if (delegate_) {
3541 delegate_->UpdateNativeEmbedRuleType(type);
3542 }
3543 }
3544
OnTextAutosizingUpdate(bool isTextAutosizing)3545 void WebPattern::OnTextAutosizingUpdate(bool isTextAutosizing)
3546 {
3547 if (delegate_) {
3548 delegate_->UpdateTextAutosizing(isTextAutosizing);
3549 }
3550 }
3551
OnKeyboardAvoidModeUpdate(const WebKeyboardAvoidMode & mode)3552 void WebPattern::OnKeyboardAvoidModeUpdate(const WebKeyboardAvoidMode& mode)
3553 {
3554 keyBoardAvoidMode_ = mode;
3555 }
3556
OnEnabledHapticFeedbackUpdate(bool enable)3557 void WebPattern::OnEnabledHapticFeedbackUpdate(bool enable)
3558 {
3559 isEnabledHapticFeedback_ = enable;
3560 }
3561
IsRootNeedExportTexture()3562 bool WebPattern::IsRootNeedExportTexture()
3563 {
3564 auto host = GetHost();
3565 CHECK_NULL_RETURN(host, false);
3566 bool isNeedExportTexture = false;
3567 for (auto parent = host->GetParent(); parent != nullptr; parent = parent->GetParent()) {
3568 RefPtr<FrameNode> frameNode = AceType::DynamicCast<FrameNode>(parent);
3569 if (!frameNode) {
3570 continue;
3571 }
3572 isNeedExportTexture = frameNode->IsNeedExportTexture();
3573 if (isNeedExportTexture) {
3574 return isNeedExportTexture;
3575 }
3576 }
3577 return isNeedExportTexture;
3578 }
3579
OnAttachContext(PipelineContext * context)3580 void WebPattern::OnAttachContext(PipelineContext *context)
3581 {
3582 nodeAttach_ = true;
3583 auto pipelineContext = Claim(context);
3584 int32_t newId = pipelineContext->GetInstanceId();
3585 instanceId_ = newId;
3586 if (delegate_) {
3587 delegate_->OnAttachContext(pipelineContext);
3588 }
3589
3590 if (observer_) {
3591 observer_->OnAttachContext(pipelineContext);
3592 }
3593
3594 if (updateInstanceIdCallback_) {
3595 updateInstanceIdCallback_(newId);
3596 }
3597
3598 if (renderContextForSurface_) {
3599 renderContextForSurface_->SetRSUIContext(context);
3600 }
3601
3602 if (renderSurface_) {
3603 renderSurface_->SetInstanceId(newId);
3604 }
3605
3606 auto host = GetHost();
3607 CHECK_NULL_VOID(host);
3608 int32_t nodeId = host->GetId();
3609
3610 pipelineContext->AddWindowStateChangedCallback(nodeId);
3611 pipelineContext->AddWindowSizeChangeCallback(nodeId);
3612 pipelineContext->AddOnAreaChangeNode(nodeId);
3613 RegisterVisibleAreaChangeCallback(pipelineContext);
3614 needUpdateWeb_ = true;
3615 RegistVirtualKeyBoardListener(pipelineContext);
3616 InitConfigChangeCallback(pipelineContext);
3617 InitializeAccessibility();
3618 InitSurfaceDensityCallback(pipelineContext);
3619 }
3620
OnDetachContext(PipelineContext * contextPtr)3621 void WebPattern::OnDetachContext(PipelineContext *contextPtr)
3622 {
3623 nodeAttach_ = false;
3624 auto context = AceType::Claim(contextPtr);
3625 CHECK_NULL_VOID(context);
3626
3627 auto host = GetHost();
3628 int32_t nodeId = host->GetId();
3629 UninitializeAccessibility();
3630 UnInitSurfaceDensityCallback(context);
3631 context->RemoveWindowStateChangedCallback(nodeId);
3632 context->RemoveWindowSizeChangeCallback(nodeId);
3633 context->RemoveOnAreaChangeNode(nodeId);
3634 context->RemoveVisibleAreaChangeNode(nodeId);
3635 context->RemoveVirtualKeyBoardCallback(nodeId);
3636 context->RemoveConfigChangedCallback(nodeId);
3637
3638 if (delegate_) {
3639 delegate_->OnDetachContext();
3640 }
3641
3642 if (observer_) {
3643 observer_->OnDetachContext();
3644 }
3645
3646 if (tooltipId_ != -1) {
3647 auto overlayManager = context->GetOverlayManager();
3648 if (overlayManager) {
3649 overlayManager->RemoveIndexerPopupById(tooltipId_);
3650 }
3651 tooltipId_ = -1;
3652 }
3653 }
3654
SetUpdateInstanceIdCallback(std::function<void (int32_t)> && callback)3655 void WebPattern::SetUpdateInstanceIdCallback(std::function<void(int32_t)>&& callback)
3656 {
3657 updateInstanceIdCallback_ = callback;
3658 }
3659
OnScrollBarColorUpdate(const std::string & value)3660 void WebPattern::OnScrollBarColorUpdate(const std::string& value)
3661 {
3662 if (delegate_) {
3663 delegate_->UpdateScrollBarColor(value);
3664 }
3665 }
3666
OnDefaultTextEncodingFormatUpdate(const std::string & value)3667 void WebPattern::OnDefaultTextEncodingFormatUpdate(const std::string& value)
3668 {
3669 if (delegate_) {
3670 delegate_->UpdateDefaultTextEncodingFormat(value);
3671 }
3672 }
3673
OnNativeVideoPlayerConfigUpdate(const std::tuple<bool,bool> & config)3674 void WebPattern::OnNativeVideoPlayerConfigUpdate(const std::tuple<bool, bool>& config)
3675 {
3676 if (delegate_) {
3677 delegate_->UpdateNativeVideoPlayerConfig(
3678 std::get<0>(config), std::get<1>(config));
3679 }
3680 }
3681
RegistVirtualKeyBoardListener(const RefPtr<PipelineContext> & pipelineContext)3682 void WebPattern::RegistVirtualKeyBoardListener(const RefPtr<PipelineContext> &pipelineContext)
3683 {
3684 if (!needUpdateWeb_) {
3685 return;
3686 }
3687 pipelineContext->SetVirtualKeyBoardCallback(GetHost()->GetId(),
3688 [weak = AceType::WeakClaim(this)](int32_t width, int32_t height, double keyboard, bool isCustomKeyboard) {
3689 auto webPattern = weak.Upgrade();
3690 CHECK_NULL_RETURN(webPattern, false);
3691 return webPattern->ProcessVirtualKeyBoard(width, height, keyboard, isCustomKeyboard);
3692 });
3693 needUpdateWeb_ = false;
3694 }
3695
InitEnhanceSurfaceFlag()3696 void WebPattern::InitEnhanceSurfaceFlag()
3697 {
3698 if (SystemProperties::GetExtSurfaceEnabled()) {
3699 isEnhanceSurface_ = true;
3700 } else {
3701 isEnhanceSurface_ = false;
3702 }
3703 }
3704
OnColorConfigurationUpdate()3705 void WebPattern::OnColorConfigurationUpdate()
3706 {
3707 auto host = GetHost();
3708 CHECK_NULL_VOID(host);
3709 if (magnifierController_) {
3710 magnifierController_->SetColorModeChange(true);
3711 host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
3712 }
3713 }
3714
OnModifyDone()3715 void WebPattern::OnModifyDone()
3716 {
3717 Pattern::OnModifyDone();
3718 // called in each update function.
3719 auto host = GetHost();
3720 CHECK_NULL_VOID(host);
3721 auto renderContext = host->GetRenderContext();
3722 CHECK_NULL_VOID(renderContext);
3723 renderContext->SetHandleChildBounds(true);
3724 if (!delegate_) {
3725 // first create case,
3726 delegate_ = AceType::MakeRefPtr<WebDelegate>(PipelineContext::GetCurrentContext(), nullptr, "",
3727 Container::CurrentId());
3728 instanceId_ = Container::CurrentId();
3729 CHECK_NULL_VOID(delegate_);
3730 observer_ = AceType::MakeRefPtr<WebDelegateObserver>(delegate_, PipelineContext::GetCurrentContext());
3731 CHECK_NULL_VOID(observer_);
3732 delegate_->SetObserver(observer_);
3733 delegate_->SetRenderMode(renderMode_);
3734 delegate_->SetFitContentMode(layoutMode_);
3735 InitEnhanceSurfaceFlag();
3736 delegate_->SetNGWebPattern(Claim(this));
3737 delegate_->SetEnhanceSurfaceFlag(isEnhanceSurface_);
3738 delegate_->SetPopup(isPopup_);
3739 delegate_->SetParentNWebId(parentNWebId_);
3740 delegate_->SetBackgroundColor(GetBackgroundColorValue(static_cast<int32_t>(
3741 renderContext->GetBackgroundColor().value_or(GetDefaultBackgroundColor()).GetValue())));
3742 if (isEnhanceSurface_) {
3743 auto drawSize = Size(1, 1);
3744 delegate_->SetDrawSize(drawSize);
3745 delegate_->InitOHOSWeb(PipelineContext::GetCurrentContext());
3746 } else {
3747 auto drawSize = Size(1, 1);
3748 delegate_->SetDrawSize(drawSize);
3749 int32_t instanceId = Container::CurrentId();
3750 CHECK_NULL_VOID(renderSurface_);
3751 CHECK_NULL_VOID(popupRenderSurface_);
3752 CHECK_NULL_VOID(renderContextForSurface_);
3753 CHECK_NULL_VOID(renderContextForPopupSurface_);
3754 renderSurface_->SetInstanceId(instanceId);
3755 popupRenderSurface_->SetInstanceId(instanceId);
3756 renderSurface_->SetRenderContext(host->GetRenderContext());
3757 if (renderMode_ == RenderMode::SYNC_RENDER) {
3758 renderSurface_->SetIsTexture(true);
3759 renderSurface_->SetBufferUsage(BUFFER_USAGE_TEXTURE + std::to_string(host->GetId()));
3760 renderSurface_->SetPatternType(PATTERN_TYPE_WEB);
3761 renderSurface_->SetSurfaceQueueSize(SYNC_SURFACE_QUEUE_SIZE);
3762 renderContextForSurface_->SetOpacity(0.0f);
3763 } else {
3764 renderSurface_->SetIsTexture(false);
3765 renderSurface_->SetBufferUsage(BUFFER_USAGE_SURFACE + std::to_string(host->GetId()));
3766 renderSurface_->SetSurfaceQueueSize(GetBufferSizeByDeviceType());
3767 renderSurface_->SetRenderContext(renderContextForSurface_);
3768 }
3769 popupRenderSurface_->SetIsTexture(false);
3770 popupRenderSurface_->SetSurfaceQueueSize(GetBufferSizeByDeviceType());
3771 popupRenderSurface_->SetRenderContext(renderContextForPopupSurface_);
3772 renderContext->AddChild(renderContextForSurface_, 0);
3773 if (SystemProperties::GetDeviceType() == DeviceType::TWO_IN_ONE) {
3774 renderContext->AddChild(renderContextForPopupSurface_, 1);
3775 }
3776 popupRenderSurface_->InitSurface();
3777 popupRenderSurface_->SetTransformHint(rotation_);
3778 popupRenderSurface_->UpdateSurfaceConfig();
3779 renderSurface_->InitSurface();
3780 renderSurface_->SetTransformHint(rotation_);
3781 TAG_LOGD(AceLogTag::ACE_WEB, "OnModify done, set rotation %{public}u", rotation_);
3782 renderSurface_->UpdateSurfaceConfig();
3783 delegate_->InitOHOSWeb(PipelineContext::GetCurrentContext(), renderSurface_);
3784 #if defined(ENABLE_ROSEN_BACKEND)
3785 delegate_->SetPopupSurface(popupRenderSurface_);
3786 #endif
3787 if (renderMode_ == RenderMode::ASYNC_RENDER) {
3788 std::string surfaceId = renderSurface_->GetUniqueId();
3789 delegate_->SetSurfaceId(surfaceId);
3790 TAG_LOGD(AceLogTag::ACE_WEB, "[getSurfaceId] set surfaceId is %{public}s", surfaceId.c_str());
3791 }
3792 }
3793 RecordWebEvent(true);
3794
3795 UpdateJavaScriptOnDocumentStartByOrder();
3796 UpdateJavaScriptOnDocumentEndByOrder();
3797 UpdateJavaScriptOnDocumentStart();
3798 UpdateJavaScriptOnDocumentEnd();
3799 UpdateJavaScriptOnHeadReadyByOrder();
3800
3801 bool isApiGteTwelve =
3802 AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE);
3803 delegate_->UpdateBackgroundColor(GetBackgroundColorValue(static_cast<int32_t>(
3804 renderContext->GetBackgroundColor().value_or(GetDefaultBackgroundColor()).GetValue())));
3805 delegate_->UpdateJavaScriptEnabled(GetJsEnabledValue(true));
3806 delegate_->UpdateBlockNetworkImage(!GetOnLineImageAccessEnabledValue(true));
3807 delegate_->UpdateLoadsImagesAutomatically(GetImageAccessEnabledValue(true));
3808 delegate_->UpdateMixedContentMode(GetMixedModeValue(MixedModeContent::MIXED_CONTENT_NEVER_ALLOW));
3809 delegate_->UpdateBypassVsyncCondition(GetBypassVsyncConditionValue(WebBypassVsyncCondition::NONE));
3810 isEmbedModeEnabled_ = GetNativeEmbedModeEnabledValue(false);
3811 if ((layoutMode_ == WebLayoutMode::FIT_CONTENT) || isEmbedModeEnabled_) {
3812 delegate_->UpdateSupportZoom(false);
3813 } else {
3814 delegate_->UpdateSupportZoom(GetZoomAccessEnabledValue(true));
3815 }
3816 delegate_->UpdateDomStorageEnabled(GetDomStorageAccessEnabledValue(false));
3817 delegate_->UpdateGeolocationEnabled(GetGeolocationAccessEnabledValue(true));
3818 delegate_->UpdateCacheMode(GetCacheModeValue(WebCacheMode::DEFAULT));
3819 if (webData_) {
3820 // Created a richtext component
3821 delegate_->SetRichtextIdentifier(webData_);
3822 delegate_->UpdateDarkMode(GetDarkModeValue(WebDarkMode::Auto));
3823 delegate_->UpdateForceDarkAccess(GetForceDarkAccessValue(true));
3824 delegate_->UpdateOverviewModeEnabled(GetOverviewModeAccessEnabledValue(false));
3825 } else {
3826 delegate_->UpdateDarkMode(GetDarkModeValue(WebDarkMode::Off));
3827 delegate_->UpdateForceDarkAccess(GetForceDarkAccessValue(false));
3828 delegate_->UpdateOverviewModeEnabled(GetOverviewModeAccessEnabledValue(true));
3829 }
3830 delegate_->UpdateAudioResumeInterval(GetAudioResumeIntervalValue(-1));
3831 delegate_->UpdateAudioExclusive(GetAudioExclusiveValue(true));
3832 delegate_->UpdateAudioSessionType(GetAudioSessionTypeValue(WebAudioSessionType::AUTO));
3833 delegate_->UpdateFileFromUrlEnabled(GetFileFromUrlAccessEnabledValue(false));
3834 delegate_->UpdateDatabaseEnabled(GetDatabaseAccessEnabledValue(false));
3835 delegate_->UpdateTextZoomRatio(GetTextZoomRatioValue(DEFAULT_TEXT_ZOOM_RATIO));
3836 auto webDebugingConfig = GetWebDebuggingAccessEnabledAndPort();
3837 if (webDebugingConfig) {
3838 bool enabled = std::get<0>(webDebugingConfig.value());
3839 int32_t port = std::get<1>(webDebugingConfig.value());
3840 if (port > 0) {
3841 delegate_->UpdateWebDebuggingAccessAndPort(enabled, port);
3842 } else {
3843 delegate_->UpdateWebDebuggingAccess(enabled);
3844 }
3845 }
3846 delegate_->UpdateMediaPlayGestureAccess(GetMediaPlayGestureAccessValue(true));
3847 delegate_->UpdatePinchSmoothModeEnabled(GetPinchSmoothModeEnabledValue(false));
3848 delegate_->UpdateMultiWindowAccess(GetMultiWindowAccessEnabledValue(false));
3849 delegate_->UpdateWebCursiveFont(GetWebCursiveFontValue(DEFAULT_CURSIVE_FONT_FAMILY));
3850 delegate_->UpdateWebFantasyFont(GetWebFantasyFontValue(DEFAULT_FANTASY_FONT_FAMILY));
3851 delegate_->UpdateWebFixedFont(GetWebFixedFontValue(DEFAULT_FIXED_fONT_FAMILY));
3852 delegate_->UpdateWebSansSerifFont(GetWebSansSerifFontValue(DEFAULT_SANS_SERIF_FONT_FAMILY));
3853 delegate_->UpdateWebSerifFont(GetWebSerifFontValue(DEFAULT_SERIF_FONT_FAMILY));
3854 delegate_->UpdateWebStandardFont(GetWebStandardFontValue(DEFAULT_STANDARD_FONT_FAMILY));
3855 delegate_->UpdateDefaultFixedFontSize(GetDefaultFixedFontSizeValue(DEFAULT_FIXED_FONT_SIZE));
3856 delegate_->UpdateDefaultFontSize(GetDefaultFontSizeValue(DEFAULT_FONT_SIZE));
3857 delegate_->UpdateDefaultTextEncodingFormat(GetDefaultTextEncodingFormatValue(DEFAULT_WEB_TEXT_ENCODING_FORMAT));
3858 delegate_->UpdateMinFontSize(GetMinFontSizeValue(DEFAULT_MINIMUM_FONT_SIZE));
3859 delegate_->UpdateMinLogicalFontSize(GetMinLogicalFontSizeValue(DEFAULT_MINIMUM_LOGICAL_FONT_SIZE));
3860 delegate_->UpdateHorizontalScrollBarAccess(GetHorizontalScrollBarAccessEnabledValue(true));
3861 delegate_->UpdateVerticalScrollBarAccess(GetVerticalScrollBarAccessEnabledValue(true));
3862 delegate_->UpdateScrollBarColor(GetScrollBarColorValue(DEFAULT_SCROLLBAR_COLOR));
3863 delegate_->UpdateOverlayScrollbarEnabled(GetOverlayScrollbarEnabledValue(false));
3864 delegate_->UpdateOverScrollMode(GetOverScrollModeValue(OverScrollMode::NEVER));
3865 delegate_->UpdateBlurOnKeyboardHideMode(GetBlurOnKeyboardHideModeValue(BlurOnKeyboardHideMode::SILENT));
3866 delegate_->UpdateCopyOptionMode(GetCopyOptionModeValue(static_cast<int32_t>(CopyOptions::Distributed)));
3867 delegate_->UpdateTextAutosizing(GetTextAutosizingValue(true));
3868 delegate_->UpdateAllowFileAccess(GetFileAccessEnabledValue(isApiGteTwelve ? false : true));
3869 delegate_->UpdateOptimizeParserBudgetEnabled(GetOptimizeParserBudgetEnabledValue(false));
3870 delegate_->UpdateWebMediaAVSessionEnabled(GetWebMediaAVSessionEnabledValue(true));
3871 delegate_->UpdateGestureFocusMode(GetGestureFocusModeValue(GestureFocusMode::DEFAULT));
3872 if (GetMetaViewport()) {
3873 delegate_->UpdateMetaViewport(GetMetaViewport().value());
3874 }
3875 if (GetBlockNetwork()) {
3876 delegate_->UpdateBlockNetwork(GetBlockNetwork().value());
3877 }
3878 if (GetUserAgent()) {
3879 delegate_->UpdateUserAgent(GetUserAgent().value());
3880 }
3881 if (GetInitialScale()) {
3882 delegate_->UpdateInitialScale(GetInitialScale().value());
3883 }
3884 isAllowWindowOpenMethod_ = SystemProperties::GetAllowWindowOpenMethodEnabled();
3885 delegate_->UpdateAllowWindowOpenMethod(GetAllowWindowOpenMethodValue(isAllowWindowOpenMethod_));
3886 delegate_->UpdateNativeEmbedModeEnabled(GetNativeEmbedModeEnabledValue(false));
3887 delegate_->UpdateIntrinsicSizeEnabled(GetIntrinsicSizeEnabledValue(false));
3888 delegate_->UpdateCssDisplayChangeEnabled(GetCssDisplayChangeEnabledValue(false));
3889 delegate_->UpdateNativeEmbedRuleTag(GetNativeEmbedRuleTagValue(""));
3890 delegate_->UpdateNativeEmbedRuleType(GetNativeEmbedRuleTypeValue(""));
3891
3892 std::tuple<bool, bool> config = GetNativeVideoPlayerConfigValue({false, false});
3893 delegate_->UpdateNativeVideoPlayerConfig(std::get<0>(config), std::get<1>(config));
3894
3895 if (GetEnableFollowSystemFontWeight()) {
3896 delegate_->UpdateEnableFollowSystemFontWeight(GetEnableFollowSystemFontWeight().value());
3897 }
3898 UpdateScrollBarWithBorderRadius();
3899 }
3900
3901 // Set the default background color when the component did not set backgroundColor()
3902 // or needSetDefaultBackgroundColor_ is true.
3903 if (!renderContext->GetBackgroundColor() || needSetDefaultBackgroundColor_) {
3904 UpdateBackgroundColor(GetDefaultBackgroundColor().GetValue());
3905 needSetDefaultBackgroundColor_ = true;
3906 }
3907
3908 // Initialize events such as keyboard, focus, etc.
3909 InitEvent();
3910 // Initialize web params.
3911 InitFeatureParam();
3912 InitializeAccessibility();
3913 // Initialize scrollupdate listener
3914 if (renderMode_ == RenderMode::SYNC_RENDER) {
3915 auto task = [weak = AceType::WeakClaim(this)]() {
3916 auto webPattern = weak.Upgrade();
3917 CHECK_NULL_VOID(webPattern);
3918 webPattern->InitSlideUpdateListener();
3919 };
3920 PostTaskToUI(std::move(task), "ArkUIWebInitSlideUpdateListener");
3921 }
3922
3923 auto embedEnabledTask = [weak = AceType::WeakClaim(this)]() {
3924 auto webPattern = weak.Upgrade();
3925 CHECK_NULL_VOID(webPattern);
3926 if (webPattern->IsRootNeedExportTexture() && webPattern->delegate_) {
3927 webPattern->delegate_->UpdateNativeEmbedModeEnabled(false);
3928 webPattern->delegate_->SetNativeInnerWeb(true);
3929 }
3930 };
3931 PostTaskToUI(std::move(embedEnabledTask), "ArkUIWebUpdateNativeEmbedModeEnabled");
3932
3933 auto pipelineContext = PipelineContext::GetCurrentContext();
3934 CHECK_NULL_VOID(pipelineContext);
3935 if (nodeAttach_) {
3936 pipelineContext->AddOnAreaChangeNode(host->GetId());
3937 }
3938 // offline mode
3939 if (host->GetNodeStatus() != NodeStatus::NORMAL_NODE) {
3940 InitInOfflineMode();
3941 }
3942 if (delegate_) {
3943 delegate_->SetSurfaceDensity(density_);
3944 }
3945 CheckAndSetWebNestedScrollExisted();
3946 UpdateScrollBarWithBorderRadius();
3947 }
3948
SetSurfaceDensity(double density)3949 void WebPattern::SetSurfaceDensity(double density)
3950 {
3951 density_ = density;
3952 }
3953
UpdateScrollBarWithBorderRadius()3954 void WebPattern::UpdateScrollBarWithBorderRadius()
3955 {
3956 auto host = GetHost();
3957 CHECK_NULL_VOID(host);
3958 auto renderContext = host->GetRenderContext();
3959 CHECK_NULL_VOID(renderContext);
3960
3961 if (!renderContext->GetBorderRadius().has_value()) {
3962 return;
3963 }
3964 auto borderRadius = renderContext->GetBorderRadius().value();
3965 auto clipState = renderContext->GetClipEdge().value_or(false);
3966
3967 bool hasBorderRadiusValue = !borderRadius.radiusTopLeft.has_value() || !borderRadius.radiusTopRight.has_value() ||
3968 !borderRadius.radiusBottomLeft.has_value() ||
3969 !borderRadius.radiusBottomRight.has_value();
3970 if (hasBorderRadiusValue) {
3971 return;
3972 }
3973
3974 CHECK_NULL_VOID(delegate_);
3975 if (clipState) {
3976 delegate_->SetBorderRadiusFromWeb(borderRadius.radiusTopLeft.value().Value(),
3977 borderRadius.radiusTopRight.value().Value(), borderRadius.radiusBottomLeft.value().Value(),
3978 borderRadius.radiusBottomRight.value().Value());
3979 } else {
3980 delegate_->SetBorderRadiusFromWeb(0.0f, 0.0f, 0.0f, 0.0f);
3981 }
3982 }
3983
3984 extern "C" {
HandleWebMessage(const char ** params,int32_t size)3985 char* HandleWebMessage(const char** params, int32_t size)
3986 {
3987 #if defined(PREVIEW) || defined(ACE_UNITTEST)
3988 return nullptr;
3989 #else
3990 if (!EventRecorder::Get().IsRecordEnable(Recorder::EventCategory::CATEGORY_WEB)) {
3991 return nullptr;
3992 }
3993 if (size < Recorder::WEB_PARAM_SIZE) {
3994 return nullptr;
3995 }
3996 for (int32_t i = 0; i < Recorder::WEB_PARAM_SIZE; i++) {
3997 if (params[i] == nullptr) {
3998 return nullptr;
3999 }
4000 }
4001 if (!EventRecorder::Get().IsMessageValid(
4002 params[Recorder::WEB_PARAM_INDEX_CATEGORY], params[Recorder::WEB_PARAM_INDEX_IDENTIFIER])) {
4003 return nullptr;
4004 }
4005 Recorder::EventParamsBuilder builder;
4006 builder.SetEventType(Recorder::EventType::WEB_ACTION)
4007 .SetEventCategory(Recorder::EventCategory::CATEGORY_WEB)
4008 .SetType(V2::WEB_ETS_TAG)
4009 .SetExtra(Recorder::KEY_WEB_CATEGORY, params[Recorder::WEB_PARAM_INDEX_CATEGORY])
4010 .SetText(params[Recorder::WEB_PARAM_INDEX_CONTENT]);
4011 EventRecorder::Get().OnEvent(std::move(builder));
4012 return nullptr;
4013 #endif
4014 }
4015 }
4016
RecordWebEvent(bool isInit)4017 void WebPattern::RecordWebEvent(bool isInit)
4018 {
4019 #if !defined(PREVIEW) && !defined(ACE_UNITTEST)
4020 TAG_LOGI(AceLogTag::ACE_WEB, "Web isInit %{public}d", isInit);
4021 CHECK_NULL_VOID(delegate_);
4022 if (isInit) {
4023 std::vector<std::pair<std::string, NativeMethodCallback>> methodList = {
4024 std::make_pair<std::string, NativeMethodCallback>(Recorder::WEB_METHOD_NAME, HandleWebMessage)
4025 };
4026 delegate_->RegisterNativeArkJSFunction(Recorder::WEB_OBJ_NAME, methodList, false);
4027 EventRecorder::Get().FillWebJsCode(onDocumentEndScriptItems_);
4028 }
4029 #endif
4030 }
4031
RunJavascriptAsync(const std::string & jsCode,std::function<void (const std::string &)> && callback)4032 bool WebPattern::RunJavascriptAsync(const std::string& jsCode, std::function<void(const std::string&)>&& callback)
4033 {
4034 #if !defined(PREVIEW) && !defined(ACE_UNITTEST)
4035 CHECK_NULL_RETURN(delegate_, false);
4036 delegate_->ExecuteTypeScript(jsCode, [cb = std::move(callback)](std::string result) { cb(result); });
4037 return true;
4038 #else
4039 return false;
4040 #endif
4041 }
4042
LoadUrlInOfflineMode()4043 void WebPattern::LoadUrlInOfflineMode()
4044 {
4045 if (!isUrlLoaded_) {
4046 isUrlLoaded_ = true;
4047 if (webSrc_) {
4048 delegate_->LoadUrl();
4049 } else if (webData_) {
4050 delegate_->LoadDataWithRichText();
4051 }
4052 }
4053 }
4054
InitInOfflineMode()4055 void WebPattern::InitInOfflineMode()
4056 {
4057 if (offlineWebInited_) {
4058 return;
4059 }
4060 ACE_SCOPED_TRACE("WebPattern::InitInOfflineMode");
4061 TAG_LOGI(AceLogTag::ACE_WEB, "Web offline mode type, webId:%{public}d", GetWebId());
4062 delegate_->OnRenderToBackground();
4063 offlineWebInited_ = true;
4064 isActive_ = false;
4065 isVisible_ = false;
4066 auto host = GetHost();
4067 CHECK_NULL_VOID(host);
4068 int width = 0;
4069 int height = 0;
4070 auto layoutProperty = host->GetLayoutProperty();
4071 CHECK_NULL_VOID(layoutProperty);
4072 auto& calcLayout = layoutProperty->GetCalcLayoutConstraint();
4073 if (calcLayout) {
4074 width = calcLayout->selfIdealSize ?
4075 calcLayout->selfIdealSize->Width()->GetDimension().ConvertToPx() : 0;
4076 height = calcLayout->selfIdealSize ?
4077 calcLayout->selfIdealSize->Height()->GetDimension().ConvertToPx() : 0;
4078 }
4079 bool isUnSetSize = (width == 0) && (height == 0);
4080 auto container = Container::Current();
4081 uint64_t displayId = 0;
4082 if (container && container->GetCurrentDisplayId() != Rosen::DISPLAY_ID_INVALID) {
4083 displayId = container->GetCurrentDisplayId();
4084 }
4085 auto defaultDisplay = OHOS::Rosen::DisplayManager::GetInstance().GetDisplayById(displayId);
4086 if (isUnSetSize && defaultDisplay) {
4087 width = defaultDisplay->GetWidth();
4088 height = defaultDisplay->GetHeight();
4089 }
4090 Size drawSize = Size(width, height);
4091 Offset offset = Offset(0, 0);
4092 TAG_LOGD(AceLogTag::ACE_WEB, "InitInOfflineMode displayId : %{public}u, drawsize_ : %{public}s",
4093 (uint32_t)displayId, drawSize_.ToString().c_str());
4094 delegate_->SetBoundsOrResize(drawSize, offset);
4095
4096 LoadUrlInOfflineMode();
4097 SetActiveStatusInner(false, true);
4098 delegate_->HideWebView();
4099 CloseContextSelectionMenu();
4100 }
4101
IsNeedResizeVisibleViewport()4102 bool WebPattern::IsNeedResizeVisibleViewport()
4103 {
4104 if (visibleViewportSize_.Width() < 0 || visibleViewportSize_.Height() < 0 ||
4105 isVirtualKeyBoardShow_ != VkState::VK_SHOW || NearZero(lastKeyboardHeight_)) {
4106 return false;
4107 }
4108 auto context = PipelineContext::GetCurrentContext();
4109 CHECK_NULL_RETURN(context, false);
4110 int32_t height = context->GetRootRect().Height();
4111 auto y = GetCoordinatePoint()->GetY();
4112 if (GreatOrEqual(height, lastKeyboardHeight_ + y)) {
4113 double newHeight = height - lastKeyboardHeight_ - y;
4114 if (GreatOrEqual(newHeight, drawSize_.Height()) ||
4115 NearEqual(newHeight, drawSize_.Height())) {
4116 visibleViewportSize_.SetWidth(-1.0);
4117 visibleViewportSize_.SetHeight(-1.0);
4118 } else {
4119 return false;
4120 }
4121 } else {
4122 visibleViewportSize_.SetWidth(-1.0);
4123 visibleViewportSize_.SetHeight(-1.0);
4124 }
4125 delegate_->ResizeVisibleViewport(visibleViewportSize_, false);
4126 return true;
4127 }
4128
ProcessVirtualKeyBoardHide(int32_t width,int32_t height,bool safeAreaEnabled)4129 bool WebPattern::ProcessVirtualKeyBoardHide(int32_t width, int32_t height, bool safeAreaEnabled)
4130 {
4131 isResizeContentAvoid_ = false;
4132 isKeyboardInSafeArea_ = false;
4133 if (safeAreaEnabled) {
4134 isVirtualKeyBoardShow_ = VkState::VK_HIDE;
4135 return false;
4136 }
4137 if (isVirtualKeyBoardShow_ != VkState::VK_SHOW) {
4138 return false;
4139 }
4140 if (layoutMode_ == WebLayoutMode::FIT_CONTENT) {
4141 TAG_LOGI(AceLogTag::ACE_WEB, "ProcessVirtualKeyBoardHide layoutMode is FIT_CONTENT");
4142 isVirtualKeyBoardShow_ = VkState::VK_HIDE;
4143 return true;
4144 }
4145 drawSize_.SetSize(drawSizeCache_);
4146 visibleViewportSize_.SetWidth(-1.0);
4147 visibleViewportSize_.SetHeight(-1.0);
4148 UpdateWebLayoutSize(width, height, false);
4149 isVirtualKeyBoardShow_ = VkState::VK_HIDE;
4150 return true;
4151 }
4152
UpdateLayoutAfterKeyboard(int32_t width,int32_t height,double keyboard)4153 bool WebPattern::UpdateLayoutAfterKeyboard(int32_t width, int32_t height, double keyboard)
4154 {
4155 auto frameNode = GetHost();
4156 CHECK_NULL_RETURN(frameNode, false);
4157 frameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
4158 auto context = PipelineContext::GetCurrentContext();
4159 CHECK_NULL_RETURN(context, false);
4160 auto taskExecutor = context->GetTaskExecutor();
4161 CHECK_NULL_RETURN(taskExecutor, false);
4162 lastKeyboardHeight_ = keyboard;
4163 keyboardGetready_ = true;
4164 taskExecutor->PostDelayedTask(
4165 [weak = WeakClaim(this), width, height]() {
4166 auto webPattern = weak.Upgrade();
4167 CHECK_NULL_VOID(webPattern);
4168 // In split-screen mode, the keyboard height is reported multiple times and is not the same.
4169 // Use the last height.
4170 webPattern->UpdateLayoutAfterKeyboardShow(width,
4171 height,
4172 webPattern->lastKeyboardHeight_,
4173 webPattern->GetDrawSize().Height());
4174 webPattern->keyboardGetready_ = false;
4175 }, TaskExecutor::TaskType::UI, UPDATE_WEB_LAYOUT_DELAY_TIME, "ArkUIWebUpdateLayoutAfterKeyboardShow");
4176 return true;
4177 }
4178
ProcessVirtualKeyBoardShow(int32_t width,int32_t height,double keyboard,bool safeAreaEnabled)4179 bool WebPattern::ProcessVirtualKeyBoardShow(int32_t width, int32_t height, double keyboard, bool safeAreaEnabled)
4180 {
4181 if (IsDialogNested()) {
4182 TAG_LOGI(AceLogTag::ACE_WEB, "ProcessVirtualKeyBoardShow, dialog nested, web don't consume keyboard event.");
4183 isKeyboardInSafeArea_ = true;
4184 return false;
4185 }
4186 if (isVirtualKeyBoardShow_ != VkState::VK_SHOW) {
4187 drawSizeCache_.SetSize(drawSize_);
4188 }
4189 if (drawSizeCache_.Height() <= (height - keyboard - GetCoordinatePoint()->GetY())) {
4190 TAG_LOGI(AceLogTag::ACE_WEB, "ProcessVirtualKeyBoardShow not obstruct");
4191 isVirtualKeyBoardShow_ = VkState::VK_SHOW;
4192 lastKeyboardHeight_ = keyboard;
4193 return !safeAreaEnabled;
4194 }
4195 if (height - GetCoordinatePoint()->GetY() < keyboard) {
4196 TAG_LOGI(AceLogTag::ACE_WEB, "ProcessVirtualKeyBoardShow Complete occlusion");
4197 isVirtualKeyBoardShow_ = VkState::VK_SHOW;
4198 return true;
4199 }
4200 if (!delegate_->NeedSoftKeyboard()) {
4201 TAG_LOGI(AceLogTag::ACE_WEB, "ProcessVirtualKeyBoardShow not NeedSoftKeyboard");
4202 return false;
4203 }
4204 isVirtualKeyBoardShow_ = VkState::VK_SHOW;
4205 if (layoutMode_ == WebLayoutMode::FIT_CONTENT) {
4206 TAG_LOGI(AceLogTag::ACE_WEB, "ProcessVirtualKeyBoardShow layoutMode is FIT_CONTENT");
4207 lastKeyboardHeight_ = keyboard;
4208 return true;
4209 }
4210 if (safeAreaEnabled) {
4211 isKeyboardInSafeArea_ = true;
4212 lastKeyboardHeight_ = keyboard;
4213 return false;
4214 }
4215
4216 if (!UpdateLayoutAfterKeyboard(width, height, keyboard)) {
4217 return false;
4218 }
4219 return true;
4220 }
4221
ProcessVirtualKeyBoard(int32_t width,int32_t height,double keyboard,bool isCustomKeyboard)4222 bool WebPattern::ProcessVirtualKeyBoard(int32_t width, int32_t height, double keyboard, bool isCustomKeyboard)
4223 {
4224 if (isUsingCustomKeyboardAvoid_) {
4225 if (!isCustomKeyboard) {
4226 // if use custom keyboard, no need to handle the system keyboard event.
4227 TAG_LOGI(AceLogTag::ACE_WEB, "ProcessVirtualKeyBoard no need to handle the system keyboard event.");
4228 return false;
4229 }
4230 }
4231 CHECK_NULL_RETURN(delegate_, false);
4232 if (delegate_->ShouldVirtualKeyboardOverlay()) {
4233 if (!IsDialogNested()) {
4234 double webKeyboard = keyboard - (height - GetCoordinatePoint()->GetY() - drawSize_.Height());
4235 webKeyboard = (webKeyboard < 0) ? 0 : webKeyboard;
4236 TAG_LOGW(AceLogTag::ACE_WEB, "VirtualKeyboard Overlaycontent is true webKeyboard:%{public}f", webKeyboard);
4237 delegate_->SetVirtualKeyBoardArg(width, height, webKeyboard);
4238 } else {
4239 delegate_->SetVirtualKeyBoardArg(width, height, 0);
4240 }
4241 } else {
4242 delegate_->SetVirtualKeyBoardArg(width, height, keyboard);
4243 }
4244
4245 auto host = GetHost();
4246 CHECK_NULL_RETURN(host, false);
4247 auto pipelineContext = host->GetContextRefPtr();
4248 CHECK_NULL_RETURN(pipelineContext, false);
4249 auto safeAreaManager = pipelineContext->GetSafeAreaManager();
4250 CHECK_NULL_RETURN(safeAreaManager, false);
4251 bool keyboardSafeAreaEnabled = safeAreaManager->KeyboardSafeAreaEnabled();
4252 TAG_LOGI(AceLogTag::ACE_WEB,
4253 "ProcessVirtualKeyBoard width:%{public}d, height:%{public}d, keyboard:%{public}f, safeArea:%{public}d", width,
4254 height, keyboard, keyboardSafeAreaEnabled);
4255 if (!isFocus_ || !isVisible_) {
4256 UpdateOnFocusTextField(false);
4257 ProcessVirtualKeyBoardHideAvoidMenu(width, height, keyboardSafeAreaEnabled);
4258 return false;
4259 }
4260 UpdateOnFocusTextField(!NearZero(keyboard));
4261 if (NearZero(keyboard)) {
4262 return ProcessVirtualKeyBoardHideAvoidMenu(width, height, keyboardSafeAreaEnabled);
4263 }
4264 return ProcessVirtualKeyBoardShowAvoidMenu(width, height, keyboard, keyboardSafeAreaEnabled);
4265 }
4266
ProcessVirtualKeyBoardShowAvoidMenu(int32_t width,int32_t height,double keyboard,bool safeAreaEnabled)4267 bool WebPattern::ProcessVirtualKeyBoardShowAvoidMenu(
4268 int32_t width, int32_t height, double keyboard, bool safeAreaEnabled)
4269 {
4270 if (ProcessVirtualKeyBoardShow(width, height, keyboard, safeAreaEnabled)) {
4271 MenuAvoidKeyboard(false, keyboard);
4272 return true;
4273 }
4274 return false;
4275 }
4276
ProcessVirtualKeyBoardHideAvoidMenu(int32_t width,int32_t height,bool safeAreaEnabled)4277 bool WebPattern::ProcessVirtualKeyBoardHideAvoidMenu(int32_t width, int32_t height, bool safeAreaEnabled)
4278 {
4279 if (ProcessVirtualKeyBoardHide(width, height, safeAreaEnabled)) {
4280 MenuAvoidKeyboard(true);
4281 return true;
4282 }
4283 return false;
4284 }
4285
UpdateWebLayoutSize(int32_t width,int32_t height,bool isKeyboard,bool isUpdate)4286 void WebPattern::UpdateWebLayoutSize(int32_t width, int32_t height, bool isKeyboard, bool isUpdate)
4287 {
4288 CHECK_NULL_VOID(delegate_);
4289 if (delegate_->ShouldVirtualKeyboardOverlay()) {
4290 TAG_LOGW(AceLogTag::ACE_WEB, "VirtualKeyboard Overlaycontent is true and does not require resizing");
4291 return;
4292 }
4293 auto frameNode = GetHost();
4294 CHECK_NULL_VOID(frameNode);
4295 auto rect = frameNode->GetRenderContext()->GetPaintRectWithoutTransform();
4296 auto offset = Offset(GetCoordinatePoint()->GetX(), GetCoordinatePoint()->GetY());
4297
4298 // Scroll focused node into view when keyboard show.
4299 TAG_LOGI(AceLogTag::ACE_WEB, "UpdateWebLayoutSize drawsize_ : %{public}s, web id : %{public}d",
4300 drawSize_.ToString().c_str(), GetWebId());
4301 delegate_->SetBoundsOrResize(drawSize_, offset, isKeyboard);
4302 delegate_->ResizeVisibleViewport(visibleViewportSize_, isKeyboard);
4303
4304 if (isUpdate) {
4305 ACE_SCOPED_TRACE("WebPattern::UpdateWebLayoutSize rect: %s", rect.ToString().c_str());
4306 if (renderMode_ == RenderMode::SYNC_RENDER) {
4307 renderSurface_->SetIsNeedSyncGeometryProperties(true);
4308 renderSurface_->SetKeyBoardAvoidRect(rect);
4309 frameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF | PROPERTY_UPDATE_RENDER);
4310 } else {
4311 rect.SetSize(SizeF(drawSize_.Width(), drawSize_.Height()));
4312 frameNode->GetRenderContext()->SyncGeometryProperties(rect);
4313 frameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
4314 }
4315 }
4316 }
4317
HandleTouchDown(const TouchEventInfo & info,bool fromOverlay)4318 void WebPattern::HandleTouchDown(const TouchEventInfo& info, bool fromOverlay)
4319 {
4320 isTouchUpEvent_ = false;
4321 InitTouchEventListener();
4322 CHECK_NULL_VOID(delegate_);
4323 Offset touchOffset = Offset(0, 0);
4324 std::list<TouchInfo> touchInfos;
4325 if (!ParseTouchInfo(info, touchInfos)) {
4326 return;
4327 }
4328 for (auto& touchPoint : touchInfos) {
4329 if (fromOverlay) {
4330 touchPoint.x -= webOffset_.GetX();
4331 touchPoint.y -= webOffset_.GetY();
4332 TAG_LOGI(AceLogTag::ACE_WEB,
4333 "SelectOverlay touch down add id:%{public}d.", touchPoint.id);
4334 touchOverlayInfo_.push_back(touchPoint);
4335 }
4336 touchPointX = touchPoint.x;
4337 touchPointY = touchPoint.y;
4338 if (info.GetSourceTool() == SourceTool::PEN &&
4339 delegate_->SetFocusByPosition(touchPointX, touchPointY) &&
4340 StylusDetectorMgr::GetInstance()->IsNeedInterceptedTouchEventForWeb(touchPointX, touchPointY)) {
4341 TAG_LOGI(AceLogTag::ACE_WEB, "stylus touch down is editable.");
4342 isNeedInterceptedTouchEvent_ = true;
4343 WebRequestFocus();
4344 return;
4345 }
4346 delegate_->HandleTouchDown(touchPoint.id, touchPoint.x, touchPoint.y, fromOverlay);
4347 if (overlayCreating_) {
4348 imageAnalyzerManager_->UpdateOverlayTouchInfo(touchPoint.x, touchPoint.y, TouchType::DOWN);
4349 }
4350 }
4351 if (IsDefaultGestureFocusMode() && !touchInfos.empty() && !GetNativeEmbedModeEnabledValue(false)) {
4352 WebRequestFocus();
4353 }
4354 }
4355
HandleTouchUp(const TouchEventInfo & info,bool fromOverlay)4356 void WebPattern::HandleTouchUp(const TouchEventInfo& info, bool fromOverlay)
4357 {
4358 isTouchUpEvent_ = true;
4359 UninitTouchEventListener();
4360 if (isNeedInterceptedTouchEvent_ && info.GetSourceTool() == SourceTool::PEN) {
4361 isNeedInterceptedTouchEvent_ = false;
4362 return;
4363 }
4364 CHECK_NULL_VOID(delegate_);
4365 if (!isReceivedArkDrag_) {
4366 ResetDragAction();
4367 }
4368 if (isDragging_) {
4369 ResetDragStateValue();
4370 }
4371 HideMagnifier();
4372 std::list<TouchInfo> touchInfos;
4373 if (!ParseTouchInfo(info, touchInfos)) {
4374 return;
4375 }
4376 touchEventInfoList_.clear();
4377 for (auto& touchPoint : touchInfos) {
4378 if (fromOverlay) {
4379 touchPoint.x -= webOffset_.GetX();
4380 touchPoint.y -= webOffset_.GetY();
4381 DelTouchOverlayInfoByTouchId(touchPoint.id);
4382 }
4383 delegate_->HandleTouchUp(touchPoint.id, touchPoint.x, touchPoint.y, fromOverlay);
4384 if (overlayCreating_) {
4385 if (imageAnalyzerManager_) {
4386 imageAnalyzerManager_->UpdateOverlayTouchInfo(touchPoint.x, touchPoint.y, TouchType::UP);
4387 }
4388 overlayCreating_ = false;
4389 }
4390 }
4391 }
4392
OnMagnifierHandleMove(const RectF & handleRect,bool isFirst)4393 void WebPattern::OnMagnifierHandleMove(const RectF& handleRect, bool isFirst)
4394 {
4395 auto localX = handleRect.GetX() - webOffset_.GetX() + handleRect.Width() / HALF;
4396 auto localY = handleRect.GetY() - webOffset_.GetY() + handleRect.Height() / HALF;
4397 ShowMagnifier(localX, localY);
4398 }
4399
HandleTouchMove(const TouchEventInfo & info,bool fromOverlay)4400 void WebPattern::HandleTouchMove(const TouchEventInfo& info, bool fromOverlay)
4401 {
4402 CHECK_EQUAL_VOID(isNeedInterceptedTouchEvent_ && info.GetSourceTool() == SourceTool::PEN, true);
4403 if (isDragging_) {
4404 return;
4405 }
4406 auto pipeline = PipelineContext::GetCurrentContext();
4407 CHECK_NULL_VOID(pipeline);
4408 auto manager = pipeline->GetDragDropManager();
4409 CHECK_NULL_VOID(manager);
4410 if (manager->IsDragged()) {
4411 return;
4412 }
4413 CHECK_NULL_VOID(delegate_);
4414 std::list<TouchInfo> touchInfos;
4415
4416 touchEventInfoList_.emplace_back(info);
4417 for (const auto& touchEventInfo : touchEventInfoList_) {
4418 ParseTouchInfo(touchEventInfo, touchInfos);
4419 }
4420
4421 if (touchInfos.empty()) {
4422 return;
4423 }
4424 if (!info.GetTouchEventsEnd()) {
4425 return;
4426 }
4427 touchEventInfoList_.clear();
4428
4429 touchInfos.sort([](const TouchInfo &point1, const TouchInfo &point2) {
4430 return point1.id < point2.id;
4431 });
4432
4433 std::vector<std::shared_ptr<OHOS::NWeb::NWebTouchPointInfo>> touch_point_infos;
4434 for (auto& touchPoint : touchInfos) {
4435 if (fromOverlay) {
4436 touchPoint.x -= webOffset_.GetX();
4437 touchPoint.y -= webOffset_.GetY();
4438 }
4439 touchPointX = touchPoint.x;
4440 touchPointY = touchPoint.y;
4441 if (magnifierController_ && magnifierController_->GetMagnifierNodeExist()) {
4442 ShowMagnifier(touchPoint.x, touchPoint.y);
4443 }
4444 std::shared_ptr<OHOS::NWeb::NWebTouchPointInfo> touch_point_info =
4445 std::make_shared<NWebTouchPointInfoImpl>(touchPoint.id, touchPoint.x, touchPoint.y);
4446 touch_point_infos.emplace_back(touch_point_info);
4447 if (overlayCreating_) {
4448 imageAnalyzerManager_->UpdateOverlayTouchInfo(touchPoint.x, touchPoint.y, TouchType::MOVE);
4449 }
4450 }
4451
4452 if (!overlayCreating_) {
4453 delegate_->HandleTouchMove(touch_point_infos, fromOverlay);
4454 }
4455 }
4456
HandleTouchCancel(const TouchEventInfo & info)4457 void WebPattern::HandleTouchCancel(const TouchEventInfo& info)
4458 {
4459 UninitTouchEventListener();
4460 if (isNeedInterceptedTouchEvent_ && info.GetSourceTool() == SourceTool::PEN) {
4461 isNeedInterceptedTouchEvent_ = false;
4462 return;
4463 }
4464 if (IsRootNeedExportTexture()) {
4465 HandleTouchUp(info, false);
4466 }
4467 CHECK_NULL_VOID(delegate_);
4468 delegate_->HandleTouchCancel();
4469 touchEventInfoList_.clear();
4470 if (overlayCreating_) {
4471 imageAnalyzerManager_->UpdateOverlayTouchInfo(0, 0, TouchType::CANCEL);
4472 overlayCreating_ = false;
4473 }
4474 HideMagnifier();
4475 }
4476
ParseTouchInfo(const TouchEventInfo & info,std::list<TouchInfo> & touchInfos)4477 bool WebPattern::ParseTouchInfo(const TouchEventInfo& info, std::list<TouchInfo>& touchInfos)
4478 {
4479 auto context = PipelineContext::GetCurrentContext();
4480 CHECK_NULL_RETURN(context, false);
4481 auto viewScale = context->GetViewScale();
4482 if (info.GetChangedTouches().empty()) {
4483 return false;
4484 }
4485 for (const auto& point : info.GetChangedTouches()) {
4486 TouchInfo touchInfo;
4487 touchInfo.id = point.GetFingerId();
4488 const Offset& location = point.GetLocalLocation();
4489 touchInfo.x = static_cast<float>(location.GetX() * viewScale);
4490 touchInfo.y = static_cast<float>(location.GetY() * viewScale);
4491 touchInfos.emplace_back(touchInfo);
4492 }
4493 return true;
4494 }
4495
RequestFullScreen()4496 void WebPattern::RequestFullScreen()
4497 {
4498 isFullScreen_ = true;
4499 }
4500
ExitFullScreen()4501 void WebPattern::ExitFullScreen()
4502 {
4503 isFullScreen_ = false;
4504 }
4505
GetCoordinatePoint()4506 std::optional<OffsetF> WebPattern::GetCoordinatePoint()
4507 {
4508 auto frameNode = GetHost();
4509 CHECK_NULL_RETURN(frameNode, std::nullopt);
4510 return frameNode->GetTransformRelativeOffset();
4511 }
4512
DelTouchOverlayInfoByTouchId(int32_t touchId)4513 void WebPattern::DelTouchOverlayInfoByTouchId(int32_t touchId)
4514 {
4515 std::list<TouchInfo>::iterator iter;
4516 for (iter = touchOverlayInfo_.begin(); iter != touchOverlayInfo_.end();) {
4517 if (iter->id == touchId) {
4518 TAG_LOGI(AceLogTag::ACE_WEB,
4519 "SelectOverlay del touch overlay info by id:%{public}d", iter->id);
4520 iter = touchOverlayInfo_.erase(iter);
4521 } else {
4522 ++iter;
4523 }
4524 }
4525 }
4526
CloseSelectOverlay()4527 void WebPattern::CloseSelectOverlay()
4528 {
4529 auto pipeline = PipelineContext::GetCurrentContext();
4530 CHECK_NULL_VOID(pipeline);
4531 if (webSelectOverlay_ && webSelectOverlay_->IsShowHandle()) {
4532 webSelectOverlay_->CloseOverlay(false, CloseReason::CLOSE_REASON_CLICK_OUTSIDE);
4533 webSelectOverlay_->SetIsShowHandle(false);
4534 for (auto& touchOverlayInfo : touchOverlayInfo_) {
4535 TAG_LOGI(AceLogTag::ACE_WEB, "SelectOverlay send touch up id:%{public}d", touchOverlayInfo.id);
4536 delegate_->HandleTouchUp(touchOverlayInfo.id, touchOverlayInfo.x, touchOverlayInfo.y, true);
4537 HideMagnifier();
4538 }
4539 touchOverlayInfo_.clear();
4540 }
4541 }
4542
ComputeMouseClippedSelectionBounds(int32_t x,int32_t y,int32_t w,int32_t h)4543 RectF WebPattern::ComputeMouseClippedSelectionBounds(int32_t x, int32_t y, int32_t w, int32_t h)
4544 {
4545 auto offset = GetCoordinatePoint().value_or(OffsetF());
4546 float selectX = offset.GetX() + x;
4547 float selectY = offset.GetY();
4548 float selectWidth = w;
4549 float selectHeight = h;
4550 if (LessOrEqual(GetHostFrameSize().value_or(SizeF()).Height(), y)) {
4551 selectY += GetHostFrameSize().value_or(SizeF()).Height();
4552 } else if (y + h <= 0) {
4553 selectY -= h;
4554 } else {
4555 selectY += y;
4556 }
4557 return RectF(selectX, selectY, selectWidth, selectHeight);
4558 }
4559
UpdateClippedSelectionBounds(int32_t x,int32_t y,int32_t w,int32_t h)4560 void WebPattern::UpdateClippedSelectionBounds(int32_t x, int32_t y, int32_t w, int32_t h)
4561 {
4562 selectArea_ = ComputeMouseClippedSelectionBounds(x, y, w, h);
4563 if (webSelectOverlay_) {
4564 webSelectOverlay_->UpdateClippedSelectionBounds(x, y, w, h);
4565 }
4566 }
4567
SelectCancel() const4568 void WebPattern::SelectCancel() const
4569 {
4570 if (isReceivedArkDrag_) {
4571 return;
4572 }
4573 if (webSelectOverlay_) {
4574 webSelectOverlay_->SelectCancel();
4575 }
4576 }
4577
IsSelectInfoValid()4578 bool WebPattern::IsSelectInfoValid()
4579 {
4580 auto info = GetSelectInfo();
4581 return !info.empty() && info != STRING_LF;
4582 }
4583
GetViewPort() const4584 std::optional<RectF> WebPattern::GetViewPort() const
4585 {
4586 CHECK_NULL_RETURN(GetHost(), std::nullopt);
4587 auto parentNode = GetHost()->GetAncestorNodeOfFrame(true);
4588 while (parentNode) {
4589 auto scrollablePattern = AceType::DynamicCast<NestableScrollContainer>(parentNode->GetPattern());
4590 auto geometryNode = parentNode->GetGeometryNode();
4591 if (scrollablePattern && geometryNode) {
4592 auto offsetRelativeToWindow = parentNode->GetOffsetRelativeToWindow();
4593 return RectF(offsetRelativeToWindow, geometryNode->GetFrameRect().GetSize());
4594 }
4595 parentNode = parentNode->GetAncestorNodeOfFrame(true);
4596 }
4597 return std::nullopt;
4598 }
4599
GetSelectInfo() const4600 std::string WebPattern::GetSelectInfo() const
4601 {
4602 CHECK_NULL_RETURN(delegate_, std::string());
4603 return delegate_->GetSelectInfo();
4604 }
4605
OnSelectionMenuOptionsUpdate(const WebMenuOptionsParam & webMenuOption)4606 void WebPattern::OnSelectionMenuOptionsUpdate(const WebMenuOptionsParam& webMenuOption)
4607 {
4608 menuOptionParam_ = std::move(webMenuOption.menuOption);
4609 for (auto& menuOption : menuOptionParam_) {
4610 std::function<void(const std::string&)> action = std::move(menuOption.action);
4611 menuOption.action = [weak = AceType::WeakClaim(this), action] (
4612 const std::string selectInfo) {
4613 auto webPattern = weak.Upgrade();
4614 CHECK_NULL_VOID(webPattern);
4615 webPattern->SelectCancel();
4616 std::string selectStr = webPattern->GetSelectInfo();
4617 if (action) {
4618 action(selectStr);
4619 }
4620 };
4621 }
4622 }
4623
UpdateEditMenuOptions(const NG::OnCreateMenuCallback && onCreateMenuCallback,const NG::OnMenuItemClickCallback && onMenuItemClick,const NG::OnPrepareMenuCallback && onPrepareMenuCallback)4624 void WebPattern::UpdateEditMenuOptions(const NG::OnCreateMenuCallback&& onCreateMenuCallback,
4625 const NG::OnMenuItemClickCallback&& onMenuItemClick, const NG::OnPrepareMenuCallback&& onPrepareMenuCallback)
4626 {
4627 onCreateMenuCallback_ = std::move(onCreateMenuCallback);
4628 onMenuItemClick_ = [weak = AceType::WeakClaim(this), action = std::move(onMenuItemClick)] (
4629 const OHOS::Ace::NG::MenuItemParam& menuItem) -> bool {
4630 auto webPattern = weak.Upgrade();
4631 bool result = false;
4632 if (action) {
4633 result = action(menuItem);
4634 }
4635 CHECK_NULL_RETURN(webPattern, result);
4636 if (!result && webPattern->IsQuickMenuShow()) {
4637 webPattern->webSelectOverlay_->HideMenu(true);
4638 }
4639 return result;
4640 };
4641 if (onPrepareMenuCallback) {
4642 onPrepareMenuCallback_ = std::move(onPrepareMenuCallback);
4643 }
4644 }
4645
UpdateDataDetectorConfig(const TextDetectConfig & config)4646 void WebPattern::UpdateDataDetectorConfig(const TextDetectConfig& config)
4647 {
4648 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::UpdateDataDetectorConfig");
4649 auto adapter = GetDataDetectorAdapter();
4650 CHECK_NULL_VOID(adapter);
4651 adapter->SetDataDetectorConfig(config);
4652 }
4653
HideHandleAndQuickMenuIfNecessary(bool hide,bool isScroll)4654 void WebPattern::HideHandleAndQuickMenuIfNecessary(bool hide, bool isScroll)
4655 {
4656 if (webSelectOverlay_) {
4657 webSelectOverlay_->HideHandleAndQuickMenuIfNecessary(hide, isScroll);
4658 }
4659 }
4660
ChangeVisibilityOfQuickMenu()4661 void WebPattern::ChangeVisibilityOfQuickMenu()
4662 {
4663 CHECK_NULL_VOID(webSelectOverlay_);
4664 webSelectOverlay_->ChangeVisibilityOfQuickMenu();
4665 }
4666
ChangeVisibilityOfQuickMenuV2()4667 bool WebPattern::ChangeVisibilityOfQuickMenuV2()
4668 {
4669 if (webSelectOverlay_ && webSelectOverlay_->IsShowHandle()) {
4670 webSelectOverlay_->ChangeVisibilityOfQuickMenu();
4671 return true;
4672 }
4673 return false;
4674 }
4675
IsQuickMenuShow()4676 bool WebPattern::IsQuickMenuShow()
4677 {
4678 CHECK_NULL_RETURN(webSelectOverlay_, false);
4679 return webSelectOverlay_->IsShowMenu();
4680 }
4681
RunQuickMenu(std::shared_ptr<OHOS::NWeb::NWebQuickMenuParams> params,std::shared_ptr<OHOS::NWeb::NWebQuickMenuCallback> callback)4682 bool WebPattern::RunQuickMenu(std::shared_ptr<OHOS::NWeb::NWebQuickMenuParams> params,
4683 std::shared_ptr<OHOS::NWeb::NWebQuickMenuCallback> callback)
4684 {
4685 if (!webSelectOverlay_) {
4686 webSelectOverlay_ = AceType::MakeRefPtr<WebSelectOverlay>(WeakClaim(this));
4687 }
4688 if (webSelectOverlay_->RunQuickMenu(params, callback)) {
4689 DestroyAnalyzerOverlay();
4690 CloseDataDetectorMenu();
4691 return true;
4692 }
4693 return false;
4694 }
4695
ShowMagnifier(int centerOffsetX,int centerOffsetY)4696 void WebPattern::ShowMagnifier(int centerOffsetX, int centerOffsetY)
4697 {
4698 if (magnifierController_) {
4699 OffsetF localOffset = OffsetF(centerOffsetX, centerOffsetY);
4700 magnifierController_->SetLocalOffset(localOffset);
4701 }
4702 }
4703
HideMagnifier()4704 void WebPattern::HideMagnifier()
4705 {
4706 TAG_LOGD(AceLogTag::ACE_WEB, "HideMagnifier");
4707 if (magnifierController_) {
4708 magnifierController_->RemoveMagnifierFrameNode();
4709 }
4710 }
4711
GetTextPaintOffset() const4712 OffsetF WebPattern::GetTextPaintOffset() const
4713 {
4714 auto frameNode = GetHost();
4715 CHECK_NULL_RETURN(frameNode, OffsetF());
4716 return frameNode->GetTransformRelativeOffset();
4717 }
4718
OnQuickMenuDismissed()4719 void WebPattern::OnQuickMenuDismissed()
4720 {
4721 CloseSelectOverlay();
4722 }
4723
DumpViewDataPageNode(RefPtr<ViewDataWrap> viewDataWrap,bool needsRecordData)4724 void WebPattern::DumpViewDataPageNode(RefPtr<ViewDataWrap> viewDataWrap, bool needsRecordData)
4725 {
4726 TAG_LOGI(AceLogTag::ACE_WEB, "called");
4727 CHECK_NULL_VOID(viewDataWrap);
4728 for (const auto& nodeInfo : pageNodeInfo_) {
4729 if (nodeInfo) {
4730 viewDataWrap->AddPageNodeInfoWrap(nodeInfo);
4731 }
4732 }
4733 viewDataWrap->SetPageUrl(viewDataCommon_->GetPageUrl());
4734 viewDataWrap->SetUserSelected(viewDataCommon_->IsUserSelected());
4735 viewDataWrap->SetOtherAccount(viewDataCommon_->IsOtherAccount());
4736 }
4737
NotifyFillRequestSuccess(RefPtr<ViewDataWrap> viewDataWrap,RefPtr<PageNodeInfoWrap> nodeWrap,AceAutoFillType autoFillType)4738 void WebPattern::NotifyFillRequestSuccess(RefPtr<ViewDataWrap> viewDataWrap,
4739 RefPtr<PageNodeInfoWrap> nodeWrap, AceAutoFillType autoFillType)
4740 {
4741 TAG_LOGI(AceLogTag::ACE_WEB, "called");
4742 CHECK_NULL_VOID(viewDataWrap);
4743 auto nodeInfoWraps = viewDataWrap->GetPageNodeInfoWraps();
4744 auto jsonNode = JsonUtil::Create(true);
4745 AceAutoFillType focusType = AceAutoFillType::ACE_UNSPECIFIED;
4746 for (const auto& nodeInfoWrap : nodeInfoWraps) {
4747 if (nodeInfoWrap == nullptr) {
4748 continue;
4749 }
4750 auto type = nodeInfoWrap->GetAutoFillType();
4751 // white list check
4752 if (ACE_AUTOFILL_TYPE_TO_NWEB.count(type) != 0) {
4753 std::string key = ACE_AUTOFILL_TYPE_TO_NWEB.at(type);
4754 if (nodeInfoWrap->GetMetadata() != IS_HINT_TYPE) {
4755 jsonNode->Put(key.c_str(), nodeInfoWrap->GetValue().c_str());
4756 } else {
4757 auto json = JsonUtil::Create(true);
4758 json->Put(OHOS::NWeb::NWEB_VIEW_DATA_KEY_PLACEHOLDER.c_str(), nodeInfoWrap->GetId());
4759 json->Put(OHOS::NWeb::NWEB_VIEW_DATA_KEY_VALUE.c_str(), nodeInfoWrap->GetValue().c_str());
4760 jsonNode->Put(key.c_str(), std::move(json));
4761 }
4762 }
4763 if (nodeInfoWrap->GetIsFocus()) {
4764 focusType = type;
4765 }
4766 }
4767 auto pageUrl = viewDataWrap->GetPageUrl();
4768 jsonNode->Put(AUTO_FILL_VIEW_DATA_PAGE_URL.c_str(), pageUrl.c_str());
4769 auto otherAccount = viewDataWrap->GetOtherAccount();
4770 jsonNode->Put(AUTO_FILL_VIEW_DATA_OTHER_ACCOUNT.c_str(), otherAccount);
4771 delegate_->NotifyAutoFillViewData(jsonNode->ToString());
4772
4773 // shift focus after autofill
4774 if (focusType != AceAutoFillType::ACE_UNSPECIFIED && !isPasswordFill_) {
4775 for (const auto& nodeInfo : pageNodeInfo_) {
4776 if (nodeInfo && nodeInfo->GetAutoFillType() == focusType) {
4777 TouchEventInfo info("autofill");
4778 TouchLocationInfo location("autofill", 0);
4779 auto rectF = nodeInfo->GetPageNodeRect();
4780 location.SetLocalLocation(
4781 Offset(rectF.GetX() - requestedWebOffset_.GetX() + (rectF.Width() / POPUP_CALCULATE_RATIO),
4782 rectF.GetY() - requestedWebOffset_.GetY() + (rectF.Height() / POPUP_CALCULATE_RATIO)));
4783 info.AddChangedTouchLocationInfo(std::move(location));
4784 HandleTouchDown(info, false);
4785 HandleTouchUp(info, false);
4786 break;
4787 }
4788 }
4789 }
4790 }
4791
NotifyFillRequestFailed(int32_t errCode,const std::string & fillContent,bool isPopup)4792 void WebPattern::NotifyFillRequestFailed(int32_t errCode, const std::string& fillContent, bool isPopup)
4793 {
4794 TAG_LOGI(AceLogTag::ACE_WEB, "called, errCode:%{public}d", errCode);
4795 if (isPasswordFill_) {
4796 delegate_->AutofillCancel(fillContent);
4797 }
4798 }
4799
ParseViewDataNumber(const std::string & key,int32_t value,RefPtr<PageNodeInfoWrap> node,RectT<float> & rect,float viewScale)4800 void WebPattern::ParseViewDataNumber(const std::string& key, int32_t value,
4801 RefPtr<PageNodeInfoWrap> node, RectT<float>& rect, float viewScale)
4802 {
4803 CHECK_NULL_VOID(viewScale > FLT_EPSILON);
4804 CHECK_NULL_VOID(node);
4805 if (key == OHOS::NWeb::NWEB_VIEW_DATA_KEY_FOCUS) {
4806 node->SetIsFocus(static_cast<bool>(value));
4807 } else if (key == OHOS::NWeb::NWEB_VIEW_DATA_KEY_RECT_X) {
4808 rect.SetLeft(value / viewScale);
4809 } else if (key == OHOS::NWeb::NWEB_VIEW_DATA_KEY_RECT_Y) {
4810 rect.SetTop(value / viewScale);
4811 } else if (key == OHOS::NWeb::NWEB_VIEW_DATA_KEY_RECT_W) {
4812 rect.SetWidth(value / viewScale);
4813 } else if (key == OHOS::NWeb::NWEB_VIEW_DATA_KEY_RECT_H) {
4814 rect.SetHeight(value / viewScale);
4815 }
4816 }
4817
ParseViewDataString(const std::string & key,const std::string & value,RefPtr<PageNodeInfoWrap> node)4818 void ParseViewDataString(const std::string& key,
4819 const std::string& value, RefPtr<PageNodeInfoWrap> node)
4820 {
4821 CHECK_NULL_VOID(node);
4822 if (key == OHOS::NWeb::NWEB_VIEW_DATA_KEY_VALUE) {
4823 node->SetValue(value);
4824 } else if (key == OHOS::NWeb::NWEB_VIEW_DATA_KEY_PLACEHOLDER) {
4825 node->SetPlaceholder(value);
4826 }
4827 }
4828
GetHintTypeAndMetadata(const std::string & attribute,RefPtr<PageNodeInfoWrap> node)4829 HintToTypeWrap WebPattern::GetHintTypeAndMetadata(const std::string& attribute, RefPtr<PageNodeInfoWrap> node)
4830 {
4831 HintToTypeWrap hintToTypeWrap;
4832 if (NWEB_AUTOFILL_TYPE_OFF == attribute) {
4833 return hintToTypeWrap;
4834 }
4835 auto placeholder = node->GetPlaceholder();
4836 if (NWEB_AUTOFILL_TYPE_TO_ACE.count(attribute) != 0) {
4837 AceAutoFillType type = NWEB_AUTOFILL_TYPE_TO_ACE.at(attribute);
4838 if (node->GetIsFocus()) {
4839 if (type == AceAutoFillType::ACE_USER_NAME || type == AceAutoFillType::ACE_PASSWORD ||
4840 type == AceAutoFillType::ACE_NEW_PASSWORD) {
4841 TAG_LOGI(AceLogTag::ACE_WEB, "The form is login fill form");
4842 isPasswordFill_ = true;
4843 }
4844 }
4845 hintToTypeWrap.autoFillType = type;
4846 } else if (!placeholder.empty()) {
4847 // try hint2Type
4848 auto host = GetHost();
4849 CHECK_NULL_RETURN(host, hintToTypeWrap);
4850 auto container = Container::Current();
4851 if (container == nullptr) {
4852 container = Container::GetActive();
4853 }
4854 CHECK_NULL_RETURN(container, hintToTypeWrap);
4855 hintToTypeWrap = container->PlaceHolderToType(placeholder);
4856 }
4857 return hintToTypeWrap;
4858 }
4859
ParseNWebViewDataNode(std::unique_ptr<JsonValue> child,std::vector<RefPtr<PageNodeInfoWrap>> & nodeInfos,int32_t nodeId)4860 void WebPattern::ParseNWebViewDataNode(std::unique_ptr<JsonValue> child,
4861 std::vector<RefPtr<PageNodeInfoWrap>>& nodeInfos, int32_t nodeId)
4862 {
4863 auto host = GetHost();
4864 CHECK_NULL_VOID(host);
4865 auto pipelineContext = host->GetContextRefPtr();
4866 CHECK_NULL_VOID(pipelineContext);
4867 float viewScale = pipelineContext->GetViewScale();
4868 CHECK_NULL_VOID(viewScale > FLT_EPSILON);
4869
4870 RefPtr<PageNodeInfoWrap> node = PageNodeInfoWrap::CreatePageNodeInfoWrap();
4871 std::string attribute = child->GetKey();
4872
4873 RectT<float> rect;
4874 int32_t len = child->GetArraySize();
4875 for (int32_t index = 0; index < len; index++) {
4876 auto object = child->GetArrayItem(index);
4877 if (object == nullptr || !object->IsObject()) {
4878 continue;
4879 }
4880 for (auto child = object->GetChild(); child && !child->IsNull(); child = child->GetNext()) {
4881 if (child->IsString()) {
4882 ParseViewDataString(child->GetKey(), child->GetString(), node);
4883 } else if (child->IsNumber()) {
4884 ParseViewDataNumber(child->GetKey(), child->GetInt(), node, rect, viewScale);
4885 }
4886 }
4887 }
4888
4889 HintToTypeWrap hintToTypeWrap = GetHintTypeAndMetadata(attribute, node);
4890 auto type = hintToTypeWrap.autoFillType;
4891 if (type != AceAutoFillType::ACE_UNSPECIFIED) {
4892 node->SetAutoFillType(type);
4893 node->SetMetadata(hintToTypeWrap.metadata);
4894 } else {
4895 return;
4896 }
4897
4898 NG::RectF rectF;
4899 rectF.SetRect(rect.GetX(), rect.GetY(), rect.Width(), rect.Height());
4900 node->SetPageNodeRect(rectF);
4901 node->SetId(nodeId);
4902 node->SetDepth(-1);
4903 nodeInfos.emplace_back(node);
4904 }
4905
ParseNWebViewDataCommonField(std::unique_ptr<JsonValue> child,const std::shared_ptr<ViewDataCommon> & viewDataCommon)4906 void WebPattern::ParseNWebViewDataCommonField(std::unique_ptr<JsonValue> child,
4907 const std::shared_ptr<ViewDataCommon>& viewDataCommon)
4908 {
4909 std::string key = child->GetKey();
4910 if (child->IsString() && key == OHOS::NWeb::NWEB_AUTOFILL_EVENT_TYPE) {
4911 std::string eventType = child->GetString();
4912 if (NWEB_AUTOFILL_EVENTS.count(eventType) != 0) {
4913 OHOS::NWeb::NWebAutofillEvent event = NWEB_AUTOFILL_EVENTS.at(eventType);
4914 viewDataCommon->SetEventType(event);
4915 }
4916 }
4917 if (child->IsString() && key == OHOS::NWeb::NWEB_AUTOFILL_PAGE_URL) {
4918 viewDataCommon->SetPageUrl(child->GetString());
4919 }
4920 if (child->IsBool() && key == OHOS::NWeb::NWEB_AUTOFILL_IS_USER_SELECTED) {
4921 viewDataCommon->SetUserSelectedFlag(child->GetBool());
4922 }
4923 if (child->IsBool() && key == OHOS::NWeb::NWEB_AUTOFILL_IS_OTHER_ACCOUNT) {
4924 viewDataCommon->SetOtherAccountFlag(child->GetBool());
4925 }
4926 if (child->IsString() && key == OHOS::NWeb::NWEB_AUTOFILL_EVENT_SOURCE) {
4927 viewDataCommon->SetSource(child->GetString());
4928 }
4929 }
4930
ParseNWebViewDataJson(const std::string & viewDataJson,std::vector<RefPtr<PageNodeInfoWrap>> & nodeInfos,const std::shared_ptr<ViewDataCommon> & viewDataCommon)4931 void WebPattern::ParseNWebViewDataJson(const std::string& viewDataJson,
4932 std::vector<RefPtr<PageNodeInfoWrap>>& nodeInfos, const std::shared_ptr<ViewDataCommon>& viewDataCommon)
4933 {
4934 nodeInfos.clear();
4935 auto sourceJson = JsonUtil::ParseJsonString(viewDataJson);
4936 if (sourceJson == nullptr || sourceJson->IsNull()) {
4937 return;
4938 }
4939
4940 int32_t nodeId = 1;
4941 int32_t len = sourceJson->GetArraySize();
4942 for (int32_t index = 0; index < len; index++) {
4943 auto object = sourceJson->GetArrayItem(index);
4944 if (object == nullptr || !object->IsObject()) {
4945 continue;
4946 }
4947 auto child = object->GetChild();
4948 if (child == nullptr || child->IsNull()) {
4949 continue;
4950 }
4951 if (child->IsArray()) {
4952 ParseNWebViewDataNode(std::move(child), nodeInfos, nodeId);
4953 nodeId++;
4954 } else {
4955 ParseNWebViewDataCommonField(std::move(child), viewDataCommon);
4956 }
4957 }
4958 }
4959
GetFocusedType()4960 AceAutoFillType WebPattern::GetFocusedType()
4961 {
4962 AceAutoFillType type = AceAutoFillType::ACE_UNSPECIFIED;
4963 for (const auto& nodeInfo : pageNodeInfo_) {
4964 if (nodeInfo && nodeInfo->GetIsFocus()) {
4965 type = static_cast<AceAutoFillType>(nodeInfo->GetAutoFillType());
4966 break;
4967 }
4968 }
4969 if (ACE_AUTOFILL_TYPE_TO_NWEB.count(type) != 0) {
4970 std::string key = ACE_AUTOFILL_TYPE_TO_NWEB.at(type);
4971 TAG_LOGI(AceLogTag::ACE_WEB, "type:%{public}s", key.c_str());
4972 }
4973 return type;
4974 }
4975
HandleAutoFillEvent()4976 bool WebPattern::HandleAutoFillEvent()
4977 {
4978 if (isPasswordFill_ && viewDataCommon_->GetSource() != OHOS::NWeb::NWEB_AUTOFILL_FOR_LOGIN) {
4979 TAG_LOGI(AceLogTag::ACE_WEB,
4980 "Handle autofill event failed! The form contains a login node, but the soruce is incorrect.");
4981 return false;
4982 }
4983
4984 auto eventType = viewDataCommon_->GetEventType();
4985 if (eventType == OHOS::NWeb::NWebAutofillEvent::FILL) {
4986 if (isPasswordFill_ && !system::GetBoolParameter(AUTO_FILL_START_POPUP_WINDOW, false)) {
4987 return RequestAutoFill(GetFocusedType());
4988 }
4989 auto host = GetHost();
4990 CHECK_NULL_RETURN(host, false);
4991 auto context = host->GetContext();
4992 CHECK_NULL_RETURN(context, false);
4993 auto taskExecutor = context->GetTaskExecutor();
4994 CHECK_NULL_RETURN(taskExecutor, false);
4995 bool fillRet = taskExecutor->PostDelayedTask(
4996 [weak = WeakClaim(this), nodeInfos = pageNodeInfo_] () {
4997 auto pattern = weak.Upgrade();
4998 CHECK_NULL_RETURN(pattern, false);
4999 return pattern->RequestAutoFill(pattern->GetFocusedType(), nodeInfos);
5000 },
5001 TaskExecutor::TaskType::UI, AUTOFILL_DELAY_TIME, "ArkUIWebHandleAutoFillEvent");
5002 return fillRet;
5003 }
5004
5005 if (eventType == OHOS::NWeb::NWebAutofillEvent::SAVE) {
5006 return RequestAutoSave();
5007 } else if (eventType == OHOS::NWeb::NWebAutofillEvent::UPDATE) {
5008 return UpdateAutoFillPopup();
5009 } else if (eventType == OHOS::NWeb::NWebAutofillEvent::CLOSE) {
5010 return CloseAutoFillPopup();
5011 }
5012
5013 return false;
5014 }
5015
HandleAutoFillEvent(const std::shared_ptr<OHOS::NWeb::NWebMessage> & viewDataJson)5016 bool WebPattern::HandleAutoFillEvent(const std::shared_ptr<OHOS::NWeb::NWebMessage>& viewDataJson)
5017 {
5018 TAG_LOGI(AceLogTag::ACE_WEB, "AutoFillEvent");
5019 viewDataCommon_ = std::make_shared<ViewDataCommon>();
5020 isPasswordFill_ = false;
5021 ParseNWebViewDataJson(viewDataJson->GetString(), pageNodeInfo_, viewDataCommon_);
5022 return HandleAutoFillEvent();
5023 }
5024
HandleAutoFillEvent(const std::shared_ptr<OHOS::NWeb::NWebHapValue> & viewDataJson)5025 bool WebPattern::HandleAutoFillEvent(const std::shared_ptr<OHOS::NWeb::NWebHapValue>& viewDataJson)
5026 {
5027 TAG_LOGI(AceLogTag::ACE_WEB, "AutoFillEvent");
5028 viewDataCommon_ = std::make_shared<ViewDataCommon>();
5029 isPasswordFill_ = false;
5030 ParseNWebViewDataJson(viewDataJson->GetString(), pageNodeInfo_, viewDataCommon_);
5031 return HandleAutoFillEvent();
5032 }
5033
RequestAutoFill(AceAutoFillType autoFillType)5034 bool WebPattern::RequestAutoFill(AceAutoFillType autoFillType)
5035 {
5036 return RequestAutoFill(autoFillType, pageNodeInfo_);
5037 }
5038
RequestAutoFill(AceAutoFillType autoFillType,const std::vector<RefPtr<PageNodeInfoWrap>> & nodeInfos)5039 bool WebPattern::RequestAutoFill(AceAutoFillType autoFillType, const std::vector<RefPtr<PageNodeInfoWrap>>& nodeInfos)
5040 {
5041 TAG_LOGI(AceLogTag::ACE_WEB, "RequestAutoFill");
5042 auto host = GetHost();
5043 CHECK_NULL_RETURN(host, false);
5044 auto context = host->GetContext();
5045 CHECK_NULL_RETURN(context, false);
5046 auto instanceId = context->GetInstanceId();
5047 CHECK_NULL_RETURN(instanceId, false);
5048 ContainerScope scope(instanceId);
5049
5050 auto offset = GetCoordinatePoint().value_or(OffsetF());
5051 for (auto& nodeInfo : nodeInfos) {
5052 auto rect = nodeInfo->GetPageNodeRect();
5053 NG::RectF rectF;
5054 rectF.SetRect(rect.GetX() + offset.GetX(), rect.GetY()+ offset.GetY(), rect.Width(), rect.Height());
5055 nodeInfo->SetPageNodeRect(rectF);
5056 }
5057 pageNodeInfo_ = nodeInfos;
5058 requestedWebOffset_ = offset;
5059
5060 auto container = Container::Current();
5061 if (container == nullptr) {
5062 container = Container::GetActive();
5063 }
5064 CHECK_NULL_RETURN(container, false);
5065 isAutoFillClosing_ = false;
5066 bool isPopup = false;
5067 return container->RequestAutoFill(host, autoFillType, false, isPopup, autoFillSessionId_, false) ==
5068 AceAutoFillError::ACE_AUTO_FILL_SUCCESS;
5069 }
5070
GetAllTextInfo() const5071 std::string WebPattern::GetAllTextInfo() const
5072 {
5073 CHECK_NULL_RETURN(delegate_, std::string());
5074 return delegate_->GetAllTextInfo();
5075 }
5076
GetSelectStartIndex() const5077 int WebPattern::GetSelectStartIndex() const
5078 {
5079 CHECK_NULL_RETURN(delegate_, 0);
5080 return delegate_->GetSelectStartIndex();
5081 }
5082
GetSelectEndIndex() const5083 int WebPattern::GetSelectEndIndex() const
5084 {
5085 CHECK_NULL_RETURN(delegate_, 0);
5086 return delegate_->GetSelectEndIndex();
5087 }
5088
GetHandleInfo(SelectOverlayInfo & infoHandle)5089 void WebPattern::GetHandleInfo(SelectOverlayInfo& infoHandle)
5090 {
5091 firstInfoHandle_ = infoHandle.firstHandle.paintRect;
5092 secondInfoHandle_ = infoHandle.secondHandle.paintRect;
5093 }
5094
GetTheme() const5095 RefPtr<TextFieldTheme> WebPattern::GetTheme() const
5096 {
5097 auto tmpHost = GetHost();
5098 CHECK_NULL_RETURN(tmpHost, nullptr);
5099 auto context = tmpHost->GetContext();
5100 CHECK_NULL_RETURN(context, nullptr);
5101 return context->GetTheme<TextFieldTheme>(tmpHost->GetThemeScopeId());
5102 }
5103
IsShowAIWrite()5104 bool WebPattern::IsShowAIWrite()
5105 {
5106 auto container = Container::Current();
5107 if (container && container->IsSceneBoardWindow()) {
5108 return false;
5109 }
5110 auto host = GetHost();
5111 CHECK_NULL_RETURN(host, false);
5112 auto textFieldTheme = GetTheme();
5113 CHECK_NULL_RETURN(textFieldTheme, false);
5114 auto bundleName = textFieldTheme->GetAIWriteBundleName();
5115 auto abilityName = textFieldTheme->GetAIWriteAbilityName();
5116 if (bundleName.empty() || abilityName.empty()) {
5117 TAG_LOGW(AceLogTag::ACE_WEB, "Failed to obtain AI write package name!");
5118 return false;
5119 }
5120 aiWriteAdapter_->SetBundleName(bundleName);
5121 aiWriteAdapter_->SetAbilityName(abilityName);
5122 auto isAISupport = textFieldTheme->GetAIWriteIsSupport() == "true";
5123 TAG_LOGI(AceLogTag::ACE_WEB, "Whether the device supports AI write: %{public}d, nodeId: %{public}d", isAISupport,
5124 host->GetId());
5125 return isAISupport;
5126 }
5127
HandleOnAIWrite()5128 void WebPattern::HandleOnAIWrite()
5129 {
5130 AIWriteInfo info;
5131 GetAIWriteInfo(info);
5132 CloseSelectOverlay();
5133 CloseKeyboard();
5134 auto callback = [weak = WeakClaim(this), info](std::vector<uint8_t>& buffer) {
5135 auto pattern = weak.Upgrade();
5136 CHECK_NULL_VOID(pattern);
5137 pattern->HandleAIWriteResult(info.selectStart, info.selectEnd, buffer);
5138 auto aiWriteAdapter = pattern->aiWriteAdapter_;
5139 CHECK_NULL_VOID(aiWriteAdapter);
5140 aiWriteAdapter->CloseModalUIExtension();
5141 };
5142
5143 auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
5144 CHECK_NULL_VOID(pipeline);
5145 aiWriteAdapter_->SetPipelineContext(pipeline);
5146 aiWriteAdapter_->ShowModalUIExtension(info, callback);
5147 }
5148
FormatIndex(int32_t & startIndex,int32_t & endIndex)5149 void WebPattern::FormatIndex(int32_t& startIndex, int32_t& endIndex)
5150 {
5151 startIndex = std::min(startIndex, endIndex);
5152 endIndex = std::max(startIndex, endIndex);
5153 startIndex = std::clamp(startIndex, 0, static_cast<int32_t>(content_.length()));
5154 endIndex = std::clamp(endIndex, 0, static_cast<int32_t>(content_.length()));
5155 }
5156
GetSelectedValue(int32_t startIndex,int32_t endIndex)5157 std::u16string WebPattern::GetSelectedValue(int32_t startIndex, int32_t endIndex)
5158 {
5159 auto allText = GetAllTextInfo();
5160 content_ = UtfUtils::Str8ToStr16(allText);
5161 FormatIndex(startIndex, endIndex);
5162 startIndex = std::clamp(startIndex, 0, static_cast<int32_t>(content_.length()));
5163 auto selectedValue = content_.substr(startIndex, endIndex - startIndex);
5164 if (selectedValue.empty()) {
5165 selectedValue = TextEmojiProcessor::SubU16string(startIndex, endIndex - startIndex, content_);
5166 }
5167 return selectedValue;
5168 }
5169
GetAIWriteInfo(AIWriteInfo & info)5170 void WebPattern::GetAIWriteInfo(AIWriteInfo& info)
5171 {
5172 info.firstHandle = firstInfoHandle_.ToString();
5173 info.secondHandle = secondInfoHandle_.ToString();
5174 info.selectStart = GetSelectStartIndex();
5175 info.selectEnd = GetSelectEndIndex();
5176
5177 // serialize the selected text
5178 auto selectContent = GetSelectInfo();
5179 std::u16string selectContentAllValue = UtfUtils::Str8ToStr16(selectContent);
5180 RefPtr<SpanString> spanString = AceType::MakeRefPtr<SpanString>(selectContentAllValue);
5181 spanString->EncodeTlv(info.selectBuffer);
5182 info.selectLength = static_cast<int32_t>(aiWriteAdapter_->GetSelectLengthOnlyText(spanString->GetU16string()));
5183
5184 // serialize the sentenced-level text
5185 auto host = GetHost();
5186 CHECK_NULL_VOID(host);
5187 auto contentAll = UtfUtils::Str8ToStr16(GetAllTextInfo());
5188 auto sentenceStart = 0;
5189 auto sentenceEnd = static_cast<int32_t>(contentAll.length());
5190 TAG_LOGD(AceLogTag::ACE_WEB, "Selected range=[%{public}d--%{public}d], content size=%{public}zu", info.selectStart,
5191 info.selectEnd, spanString->GetString().size());
5192 for (int32_t i = info.selectStart; i >= 0; --i) {
5193 if (aiWriteAdapter_->IsSentenceBoundary(contentAll[i])) {
5194 sentenceStart = i + 1;
5195 break;
5196 }
5197 }
5198 for (int32_t i = info.selectEnd; i < info.selectLength; i++) {
5199 if (aiWriteAdapter_->IsSentenceBoundary(contentAll[i])) {
5200 sentenceEnd = i;
5201 break;
5202 }
5203 }
5204 info.start = info.selectStart - sentenceStart;
5205 info.end = info.selectEnd - sentenceStart;
5206 auto sentenceContent = GetSelectedValue(sentenceStart, sentenceEnd);
5207 spanString = AceType::MakeRefPtr<SpanString>(sentenceContent);
5208 spanString->EncodeTlv(info.sentenceBuffer);
5209 TAG_LOGD(AceLogTag::ACE_WEB, "Sentence range=[%{public}d--%{public}d], content size=%{public}zu", sentenceStart,
5210 sentenceEnd, spanString->GetString().size());
5211 info.componentType = host->GetTag();
5212 }
5213
HandleAIWriteResult(int32_t start,int32_t end,std::vector<uint8_t> & buffer)5214 void WebPattern::HandleAIWriteResult(int32_t start, int32_t end, std::vector<uint8_t>& buffer)
5215 {
5216 return;
5217 }
5218
RequestAutoSave()5219 bool WebPattern::RequestAutoSave()
5220 {
5221 TAG_LOGI(AceLogTag::ACE_WEB, "RequestAutoSave");
5222 auto host = GetHost();
5223 CHECK_NULL_RETURN(host, false);
5224 auto context = host->GetContext();
5225 CHECK_NULL_RETURN(context, false);
5226 auto instanceId = context->GetInstanceId();
5227 CHECK_NULL_RETURN(instanceId, false);
5228 ContainerScope scope(instanceId);
5229 auto container = Container::Current();
5230 if (container == nullptr) {
5231 container = Container::GetActive();
5232 }
5233 CHECK_NULL_RETURN(container, false);
5234 return container->RequestAutoSave(host, nullptr, nullptr, false);
5235 }
5236
UpdateAutoFillPopup()5237 bool WebPattern::UpdateAutoFillPopup()
5238 {
5239 TAG_LOGI(AceLogTag::ACE_WEB, "UpdateAutoFillPopup");
5240 if (isAutoFillClosing_) {
5241 return false;
5242 }
5243 auto host = GetHost();
5244 CHECK_NULL_RETURN(host, false);
5245 auto context = host->GetContext();
5246 CHECK_NULL_RETURN(context, false);
5247 auto instanceId = context->GetInstanceId();
5248 CHECK_NULL_RETURN(instanceId, false);
5249 ContainerScope scope(instanceId);
5250 auto container = Container::Current();
5251 if (container == nullptr) {
5252 container = Container::GetActive();
5253 }
5254 CHECK_NULL_RETURN(container, false);
5255 return container->UpdatePopupUIExtension(host, autoFillSessionId_, false);
5256 }
5257
CloseAutoFillPopup()5258 bool WebPattern::CloseAutoFillPopup()
5259 {
5260 TAG_LOGI(AceLogTag::ACE_WEB, "CloseAutoFillPopup");
5261 auto host = GetHost();
5262 CHECK_NULL_RETURN(host, false);
5263 auto context = host->GetContext();
5264 CHECK_NULL_RETURN(context, false);
5265 auto instanceId = context->GetInstanceId();
5266 CHECK_NULL_RETURN(instanceId, false);
5267 ContainerScope scope(instanceId);
5268 auto container = Container::Current();
5269 if (container == nullptr) {
5270 container = Container::GetActive();
5271 }
5272 CHECK_NULL_RETURN(container, false);
5273 isAutoFillClosing_ = true;
5274 return container->ClosePopupUIExtension(autoFillSessionId_);
5275 }
5276
5277
OnTouchSelectionChanged(std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> insertHandle,std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> startSelectionHandle,std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> endSelectionHandle)5278 void WebPattern::OnTouchSelectionChanged(std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> insertHandle,
5279 std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> startSelectionHandle,
5280 std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> endSelectionHandle)
5281 {
5282 if (!webSelectOverlay_) {
5283 return;
5284 }
5285 webSelectOverlay_->OnTouchSelectionChanged(insertHandle, startSelectionHandle, endSelectionHandle);
5286 }
5287
OnCursorChange(const OHOS::NWeb::CursorType & cursorType,std::shared_ptr<OHOS::NWeb::NWebCursorInfo> cursorInfo)5288 bool WebPattern::OnCursorChange(
5289 const OHOS::NWeb::CursorType& cursorType, std::shared_ptr<OHOS::NWeb::NWebCursorInfo> cursorInfo)
5290 {
5291 auto [type, info] = GetAndUpdateCursorStyleInfo(cursorType, cursorInfo);
5292 if (mouseEventDeviceId_ == RESERVED_DEVICEID1 || mouseEventDeviceId_ == RESERVED_DEVICEID2) {
5293 TAG_LOGD(AceLogTag::ACE_WEB, "OnCursorChange this device id is reserved.");
5294 return false;
5295 }
5296 if (isHoverExit_) {
5297 TAG_LOGD(AceLogTag::ACE_WEB, "OnCursorChange reciving unexpected hide command");
5298 return false;
5299 }
5300 auto pipeline = PipelineContext::GetCurrentContext();
5301 CHECK_NULL_RETURN(pipeline, false);
5302 auto windowId = pipeline->GetWindowId();
5303 auto mouseStyle = MouseStyle::CreateMouseStyle();
5304 int32_t curPointerStyle = 0;
5305 if (mouseStyle->GetPointerStyle(windowId, curPointerStyle) == -1) {
5306 return false;
5307 }
5308
5309 if ((type == OHOS::NWeb::CursorType::CT_CONTEXTMENU) || (type == OHOS::NWeb::CursorType::CT_ALIAS)) {
5310 UpdateLocalCursorStyle(windowId, type);
5311 } else if (type == OHOS::NWeb::CursorType::CT_CUSTOM) {
5312 UpdateCustomCursor(windowId, info);
5313 } else {
5314 MouseFormat pointStyle = MouseFormat::DEFAULT;
5315 int64_t idx = BinarySearchFindIndex(g_cursorTypeMap, ArraySize(g_cursorTypeMap), type);
5316 if (idx >= 0) {
5317 pointStyle = g_cursorTypeMap[idx].value;
5318 }
5319 mouseStyle->SetPointerVisible(pointStyle);
5320 if (static_cast<int32_t>(pointStyle) != curPointerStyle) {
5321 mouseStyle->SetPointerStyle(windowId, pointStyle);
5322 }
5323 }
5324 return true;
5325 }
5326
GetAndUpdateCursorStyleInfo(const OHOS::NWeb::CursorType & cursorType,std::shared_ptr<OHOS::NWeb::NWebCursorInfo> cursorInfo)5327 CursorStyleInfo WebPattern::GetAndUpdateCursorStyleInfo(
5328 const OHOS::NWeb::CursorType& cursorType, std::shared_ptr<OHOS::NWeb::NWebCursorInfo> cursorInfo)
5329 {
5330 auto type = cursorType;
5331 auto info = cursorInfo;
5332 if (type == OHOS::NWeb::CursorType::CT_LOCK) {
5333 type = OHOS::NWeb::CursorType::CT_NONE;
5334 isMouseLocked_ = true;
5335 } else if (type == OHOS::NWeb::CursorType::CT_UNLOCK) {
5336 type = cursorType_;
5337 info = nweb_cursorInfo_;
5338 isMouseLocked_ = false;
5339 } else {
5340 if (cursorType_ != type) {
5341 TAG_LOGI(AceLogTag::ACE_WEB, "OnCursorChange type: %{public}d isHoverExit: %{public}d", type, isHoverExit_);
5342 cursorType_ = type;
5343 }
5344 nweb_cursorInfo_.reset();
5345 if (type == OHOS::NWeb::CursorType::CT_CUSTOM) {
5346 nweb_cursorInfo_ = info;
5347 }
5348 }
5349 return std::make_tuple(type, info);
5350 }
5351
UpdateLocalCursorStyle(int32_t windowId,const OHOS::NWeb::CursorType & type)5352 void WebPattern::UpdateLocalCursorStyle(int32_t windowId, const OHOS::NWeb::CursorType& type)
5353 {
5354 std::shared_ptr<Media::PixelMap> pixelMap;
5355 auto mouseStyle = MouseStyle::CreateMouseStyle();
5356 if (type == NWeb::CursorType::CT_CONTEXTMENU) {
5357 MouseFormat pointStyle = MouseFormat::CONTEXT_MENU;
5358 pixelMap = CreatePixelMapFromString(IMAGE_POINTER_CONTEXT_MENU_PATH);
5359 mouseStyle->SetMouseIcon(windowId, pointStyle, pixelMap);
5360 } else if (type == NWeb::CursorType::CT_ALIAS) {
5361 MouseFormat pointStyle = MouseFormat::ALIAS;
5362 pixelMap = CreatePixelMapFromString(IMAGE_POINTER_ALIAS_PATH);
5363 mouseStyle->SetMouseIcon(windowId, pointStyle, pixelMap);
5364 }
5365 }
5366
GetPixelMapName(std::shared_ptr<Media::PixelMap> pixelMap,std::string featureName)5367 std::string WebPattern::GetPixelMapName(std::shared_ptr<Media::PixelMap> pixelMap, std::string featureName)
5368 {
5369 if (!pixelMap) {
5370 TAG_LOGE(AceLogTag::ACE_WEB, "GetPixelMapName error, PixelMap is null");
5371 return "undefined_";
5372 }
5373 auto frameNode = GetHost();
5374 CHECK_NULL_RETURN(frameNode, "undefined_");
5375 std::string memNameStr = "web-" + std::to_string(pixelMap->GetWidth()) + "x" +
5376 std::to_string(pixelMap->GetHeight()) + "-" + featureName + "-" +
5377 std::to_string(frameNode->GetId());
5378 return memNameStr;
5379 }
5380
UpdateCustomCursor(int32_t windowId,std::shared_ptr<OHOS::NWeb::NWebCursorInfo> info)5381 void WebPattern::UpdateCustomCursor(int32_t windowId, std::shared_ptr<OHOS::NWeb::NWebCursorInfo> info)
5382 {
5383 int32_t x = 0;
5384 int32_t y = 0;
5385 int32_t width = 0;
5386 int32_t height = 0;
5387 uint8_t *buff = nullptr;
5388 if (info) {
5389 x = info->GetX();
5390 y = info->GetY();
5391 buff = info->GetBuff();
5392 width = info->GetWidth();
5393 height = info->GetHeight();
5394 }
5395 Media::InitializationOptions opt;
5396 opt.size.width = width;
5397 opt.size.height = height;
5398 opt.editable = true;
5399 auto pixelMap = Media::PixelMap::Create(opt);
5400 CHECK_NULL_VOID(pixelMap);
5401 uint64_t bufferSize = static_cast<uint64_t>(width * height * IMAGE_POINTER_CUSTOM_CHANNEL);
5402 uint32_t status = pixelMap->WritePixels(static_cast<const uint8_t*>(buff), bufferSize);
5403 if (status != 0) {
5404 TAG_LOGE(AceLogTag::ACE_WEB, "write pixel map failed %{public}u", status);
5405 return;
5406 }
5407 std::shared_ptr<Media::PixelMap> cursorPixelMap(pixelMap.release());
5408 CHECK_NULL_VOID(cursorPixelMap);
5409 auto host = GetHost();
5410 CHECK_NULL_VOID(host);
5411 auto pipeline = host->GetContextRefPtr();
5412 CHECK_NULL_VOID(pipeline);
5413 float dipScale = pipeline->GetDipScale();
5414 cursorPixelMap->scale(dipScale, dipScale);
5415
5416 auto mouseStyle = MouseStyle::CreateMouseStyle();
5417 CHECK_NULL_VOID(mouseStyle);
5418 uint32_t res = cursorPixelMap->SetMemoryName(GetPixelMapName(cursorPixelMap, "cursor"));
5419 TAG_LOGI(AceLogTag::ACE_WEB, "SetMemoryName result is %{public}d", res);
5420 mouseStyle->SetCustomCursor(windowId, x * dipScale, y * dipScale, cursorPixelMap);
5421 }
5422
CreatePixelMapFromString(const std::string & filePath)5423 std::shared_ptr<OHOS::Media::PixelMap> WebPattern::CreatePixelMapFromString(const std::string& filePath)
5424 {
5425 OHOS::Media::SourceOptions opts;
5426 opts.formatHint = "image/svg+xml";
5427 uint32_t errCode = 0;
5428 auto imageSource = OHOS::Media::ImageSource::CreateImageSource(filePath, opts, errCode);
5429 CHECK_NULL_RETURN(imageSource, nullptr);
5430 std::set<std::string> formats;
5431 errCode = imageSource->GetSupportedFormats(formats);
5432 Media::DecodeOptions decodeOpts;
5433 std::shared_ptr<OHOS::Media::PixelMap> pixelMap = imageSource->CreatePixelMap(decodeOpts, errCode);
5434 CHECK_NULL_RETURN(pixelMap, nullptr);
5435
5436 return pixelMap;
5437 }
5438
OnTooltip(const std::string & tooltip)5439 void WebPattern::OnTooltip(const std::string& tooltip)
5440 {
5441 auto pipeline = PipelineContext::GetCurrentContext();
5442 CHECK_NULL_VOID(pipeline);
5443 auto overlayManager = pipeline->GetOverlayManager();
5444 CHECK_NULL_VOID(overlayManager);
5445 tooltipTimestamp_ = GetSysTimestamp();
5446 auto tooltipTimestamp = tooltipTimestamp_;
5447
5448 if (tooltipId_ != -1) {
5449 overlayManager->RemoveIndexerPopupById(tooltipId_);
5450 tooltipId_ = -1;
5451 }
5452 auto tooltipText = tooltip;
5453 OHOS::Ace::StringUtils::TrimStrLeadingAndTrailing(tooltipText);
5454 if (tooltipText == "" || mouseHoveredX_ < 0 || mouseHoveredY_ < 0) {
5455 return;
5456 }
5457 ShowTooltip(tooltipText, tooltipTimestamp);
5458 }
5459
OnPopupSize(int32_t x,int32_t y,int32_t width,int32_t height)5460 void WebPattern::OnPopupSize(int32_t x, int32_t y, int32_t width, int32_t height)
5461 {
5462 CHECK_NULL_VOID(renderContextForPopupSurface_);
5463 TAG_LOGI(AceLogTag::ACE_WEB,
5464 "Web %{public}d popup window resize to (x:%{public}d, y:%{public}d, width:%{public}d, height:%{public}d)",
5465 GetWebId(), x, y, width, height);
5466 renderContextForPopupSurface_->SetBounds(x, y, width, height);
5467 }
5468
OnPopupShow(bool show)5469 void WebPattern::OnPopupShow(bool show)
5470 {
5471 if (!show) {
5472 CHECK_NULL_VOID(renderContextForPopupSurface_);
5473 renderContextForPopupSurface_->SetBounds(0, 0, 0, 0);
5474 }
5475
5476 TAG_LOGI(AceLogTag::ACE_WEB, "Web %{public}d show popup window %{public}d", GetWebId(), show);
5477 auto pipeline = GetContext();
5478 CHECK_NULL_VOID(pipeline);
5479 pipeline->RequestFrame();
5480 }
5481
GetVisibleRectToWeb(int & visibleX,int & visibleY,int & visibleWidth,int & visibleHeight)5482 void WebPattern::GetVisibleRectToWeb(int& visibleX, int& visibleY, int& visibleWidth, int& visibleHeight)
5483 {
5484 auto host = GetHost();
5485 CHECK_NULL_VOID(host);
5486 RectF visibleRect;
5487 RectF visibleInnerRect;
5488 RectF frameRect;
5489 host->GetVisibleRectWithClip(visibleRect, visibleInnerRect, frameRect);
5490 auto offset = GetCoordinatePoint().value_or(OffsetF());
5491 visibleX = visibleInnerRect.GetX() - offset.GetX();
5492 visibleY = visibleInnerRect.GetY() - offset.GetY();
5493 visibleWidth = visibleInnerRect.Width();
5494 visibleHeight = visibleInnerRect.Height();
5495 }
5496
RestoreRenderFit()5497 void WebPattern::RestoreRenderFit()
5498 {
5499 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::RestoreRenderFit, webId: %{public}d, isRotation: %{public}d",
5500 GetWebId(), isRotating_);
5501 if (isRotating_) {
5502 return;
5503 }
5504 if (renderContextForSurface_) {
5505 renderContextForSurface_->SetRenderFit(RenderFit::TOP_LEFT);
5506 }
5507 }
5508
AttachCustomKeyboard()5509 void WebPattern::AttachCustomKeyboard()
5510 {
5511 TAG_LOGI(AceLogTag::ACE_WEB, "WebCustomKeyboard AttachCustomKeyboard enter");
5512 CHECK_NULL_VOID(customKeyboardBuilder_);
5513 auto frameNode = GetHost();
5514 CHECK_NULL_VOID(frameNode);
5515 auto pipeline = PipelineContext::GetCurrentContextSafely();
5516 CHECK_NULL_VOID(pipeline);
5517 auto overlayManager = pipeline->GetOverlayManager();
5518 CHECK_NULL_VOID(overlayManager);
5519 overlayManager->SetCustomKeyboardOption(true);
5520 overlayManager->BindKeyboard(customKeyboardBuilder_, frameNode->GetId());
5521 keyboardOverlay_ = overlayManager;
5522 keyboardOverlay_->AvoidCustomKeyboard(frameNode->GetId(), 0);
5523 isUsingCustomKeyboardAvoid_ = true;
5524 TAG_LOGI(AceLogTag::ACE_WEB, "WebCustomKeyboard AttachCustomKeyboard end");
5525 }
5526
CloseCustomKeyboard()5527 void WebPattern::CloseCustomKeyboard()
5528 {
5529 TAG_LOGI(AceLogTag::ACE_WEB, "WebCustomKeyboard CloseCustomKeyboard enter");
5530 auto frameNode = GetHost();
5531 CHECK_NULL_VOID(frameNode);
5532 CHECK_NULL_VOID(keyboardOverlay_);
5533 keyboardOverlay_->CloseKeyboard(frameNode->GetId());
5534 isUsingCustomKeyboardAvoid_ = false;
5535 TAG_LOGI(AceLogTag::ACE_WEB, "WebCustomKeyboard CloseCustomKeyboard end");
5536 MenuAvoidKeyboard(true);
5537 }
5538
HandleShowTooltip(const std::string & tooltip,int64_t tooltipTimestamp)5539 void WebPattern::HandleShowTooltip(const std::string& tooltip, int64_t tooltipTimestamp)
5540 {
5541 if ((tooltipTimestamp_ != tooltipTimestamp) || (tooltip == "")) {
5542 return;
5543 }
5544 auto pipeline = PipelineContext::GetCurrentContext();
5545 CHECK_NULL_VOID(pipeline);
5546 auto overlayManager = pipeline->GetOverlayManager();
5547 CHECK_NULL_VOID(overlayManager);
5548 if (tooltipId_ == -1) {
5549 tooltipId_ = ElementRegister::GetInstance()->MakeUniqueId();
5550 }
5551 auto tooltipNode = FrameNode::GetOrCreateFrameNode(V2::TEXT_ETS_TAG, tooltipId_,
5552 []() { return AceType::MakeRefPtr<TextPattern>(); });
5553 CHECK_NULL_VOID(tooltipNode);
5554
5555 auto textRenderContext = tooltipNode->GetRenderContext();
5556 CHECK_NULL_VOID(textRenderContext);
5557 auto textLayoutProperty = tooltipNode->GetLayoutProperty<TextLayoutProperty>();
5558 CHECK_NULL_VOID(textLayoutProperty);
5559 textLayoutProperty->UpdateContent(tooltip);
5560
5561 BorderWidthProperty borderWidth;
5562 borderWidth.SetBorderWidth(TOOLTIP_BORDER_WIDTH);
5563 textLayoutProperty->UpdateBorderWidth(borderWidth);
5564 textLayoutProperty->UpdateFontSize(TOOLTIP_FONT_SIZE);
5565 textLayoutProperty->UpdatePadding({ CalcLength(TOOLTIP_PADDING),
5566 CalcLength(TOOLTIP_PADDING), CalcLength(TOOLTIP_PADDING), CalcLength(TOOLTIP_PADDING) });
5567 textLayoutProperty->UpdateCalcMaxSize(CalcSize(CalcLength(Dimension(
5568 pipeline->GetCurrentRootWidth() * TOOLTIP_MAX_PORTION)), std::nullopt));
5569 UpdateTooltipContentColor(tooltipNode);
5570
5571 OffsetF tooltipOffset;
5572 CalculateTooltipOffset(tooltipNode, tooltipOffset);
5573 textRenderContext->UpdatePosition(OffsetT<Dimension>(Dimension(tooltipOffset.GetX()),
5574 Dimension(tooltipOffset.GetY())));
5575
5576 BorderRadiusProperty borderRadius;
5577 borderRadius.SetRadius(TOOLTIP_BORDER_RADIUS);
5578 textRenderContext->SetBorderRadius(borderRadius);
5579
5580 Shadow shadow;
5581 if (GetShadowFromTheme(ShadowStyle::OuterDefaultSM, shadow)) {
5582 textRenderContext->UpdateBackShadow(shadow);
5583 }
5584
5585 BorderColorProperty borderColor;
5586 borderColor.SetColor(Color::BLACK);
5587 textRenderContext->UpdateBorderColor(borderColor);
5588 overlayManager->ShowIndexerPopup(tooltipId_, tooltipNode);
5589 }
5590
GetShadowFromTheme(ShadowStyle shadowStyle,Shadow & shadow)5591 bool WebPattern::GetShadowFromTheme(ShadowStyle shadowStyle, Shadow& shadow)
5592 {
5593 if (shadowStyle == ShadowStyle::None) {
5594 return true;
5595 }
5596 auto host = GetHost();
5597 CHECK_NULL_RETURN(host, false);
5598 auto pipelineContext = host->GetContextRefPtr();
5599 CHECK_NULL_RETURN(pipelineContext, false);
5600 auto colorMode = pipelineContext->GetColorMode();
5601 auto shadowTheme = pipelineContext->GetTheme<ShadowTheme>();
5602 CHECK_NULL_RETURN(shadowTheme, false);
5603 shadow = shadowTheme->GetShadow(shadowStyle, colorMode);
5604 return true;
5605 }
5606
5607
UpdateTooltipContentColor(const RefPtr<FrameNode> & textNode)5608 void WebPattern::UpdateTooltipContentColor(const RefPtr<FrameNode>& textNode)
5609 {
5610 CHECK_NULL_VOID(textNode);
5611 auto textRenderContext = textNode->GetRenderContext();
5612 CHECK_NULL_VOID(textRenderContext);
5613 auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
5614 CHECK_NULL_VOID(textLayoutProperty);
5615
5616 if (Color::BLACK == GetSystemColor()) {
5617 textLayoutProperty->UpdateTextColor(Color::WHITE);
5618 textRenderContext->UpdateBackgroundColor(Color::BLACK);
5619 } else {
5620 textLayoutProperty->UpdateTextColor(Color::BLACK);
5621 textRenderContext->UpdateBackgroundColor(Color::WHITE);
5622 }
5623 }
5624
ShowTooltip(const std::string & tooltip,int64_t tooltipTimestamp)5625 void WebPattern::ShowTooltip(const std::string& tooltip, int64_t tooltipTimestamp)
5626 {
5627 auto tooltipTask = [weak = WeakClaim(this), tooltip, tooltipTimestamp]() {
5628 auto pattern = weak.Upgrade();
5629 CHECK_NULL_VOID(pattern);
5630 pattern->HandleShowTooltip(tooltip, tooltipTimestamp);
5631 };
5632
5633 auto host = GetHost();
5634 CHECK_NULL_VOID(host);
5635 auto context = host->GetContext();
5636 CHECK_NULL_VOID(context);
5637
5638 auto taskExecutor = context->GetTaskExecutor();
5639 CHECK_NULL_VOID(taskExecutor);
5640
5641 taskExecutor->PostDelayedTask(tooltipTask, TaskExecutor::TaskType::UI, TOOLTIP_DELAY_MS, "ArkUIWebShowTooltip");
5642 }
5643
CalculateTooltipOffset(RefPtr<FrameNode> & tooltipNode,OffsetF & tooltipOffset)5644 void WebPattern::CalculateTooltipOffset(RefPtr<FrameNode>& tooltipNode, OffsetF& tooltipOffset)
5645 {
5646 auto textLayoutWrapper = tooltipNode->CreateLayoutWrapper(true);
5647 CHECK_NULL_VOID(textLayoutWrapper);
5648 textLayoutWrapper->Measure(std::nullopt);
5649 auto textGeometryNode = textLayoutWrapper->GetGeometryNode();
5650 CHECK_NULL_VOID(textGeometryNode);
5651 auto textWidth = textGeometryNode->GetMarginFrameSize().Width();
5652 auto textHeight = textGeometryNode->GetMarginFrameSize().Height();
5653
5654 auto offset = GetCoordinatePoint().value_or(OffsetF());
5655 auto pipeline = PipelineContext::GetCurrentContext();
5656 CHECK_NULL_VOID(pipeline);
5657 auto overlayManager = pipeline->GetOverlayManager();
5658 CHECK_NULL_VOID(overlayManager);
5659 auto rootNode = AceType::DynamicCast<FrameNode>(overlayManager->GetRootNode().Upgrade());
5660 CHECK_NULL_VOID(rootNode);
5661 auto root = rootNode->GetTransformRectRelativeToWindow();
5662
5663 auto offsetX = offset.GetX() - root.GetX() + mouseHoveredX_ + TOOLTIP_MARGIN;
5664 auto offsetY = offset.GetY() - root.GetY() + mouseHoveredY_ + TOOLTIP_MARGIN;
5665
5666 ScopedLayout scope(Referenced::RawPtr(pipeline));
5667 if (GreatNotEqual(offsetX + textWidth, root.Width())) {
5668 offsetX = root.Width() - textWidth;
5669 }
5670 if (GreatNotEqual(offsetY + textHeight, root.Height())) {
5671 offsetY = root.Height() - textHeight;
5672 }
5673 tooltipOffset.SetX(offsetX);
5674 tooltipOffset.SetY(offsetY);
5675 TAG_LOGI(AceLogTag::ACE_WEB,
5676 "CalculateTooltipOffset [Tooltip] width: %{public}f height: %{public}f offset:(%{public}f, %{public}f)"
5677 " [Web] width: %{public}f height: %{public}f offset:(%{public}f, %{public}f)",
5678 textWidth, textHeight, offsetX, offsetY, drawSize_.Width(), drawSize_.Height(), offset.GetX(), offset.GetY());
5679 }
5680
OnSelectPopupMenu(std::shared_ptr<OHOS::NWeb::NWebSelectPopupMenuParam> params,std::shared_ptr<OHOS::NWeb::NWebSelectPopupMenuCallback> callback)5681 void WebPattern::OnSelectPopupMenu(std::shared_ptr<OHOS::NWeb::NWebSelectPopupMenuParam> params,
5682 std::shared_ptr<OHOS::NWeb::NWebSelectPopupMenuCallback> callback)
5683 {
5684 CHECK_NULL_VOID(params);
5685 CHECK_NULL_VOID(callback);
5686 auto host = GetHost();
5687 CHECK_NULL_VOID(host);
5688 auto eventHub = host->GetOrCreateEventHub<WebEventHub>();
5689 CHECK_NULL_VOID(eventHub);
5690 auto context = PipelineContext::GetCurrentContext();
5691 CHECK_NULL_VOID(context);
5692 auto overlayManager = context->GetOverlayManager();
5693 CHECK_NULL_VOID(overlayManager);
5694
5695 auto id = host->GetId();
5696 std::vector<SelectParam> selectParam;
5697 for (auto& item : params->GetMenuItems()) {
5698 selectParam.push_back({
5699 item->GetLabel(), ""
5700 });
5701 }
5702 bool autoWrapFlag = true;
5703 auto menu = MenuView::Create(selectParam, id, host->GetTag(), autoWrapFlag);
5704 CHECK_NULL_VOID(menu);
5705 auto menuWrapperPattern = menu->GetPattern<MenuWrapperPattern>();
5706 CHECK_NULL_VOID(menuWrapperPattern);
5707 auto destructor = [weak = WeakClaim(this), id]() {
5708 auto pattern = weak.Upgrade();
5709 CHECK_NULL_VOID(pattern);
5710 auto pipeline = NG::PipelineContext::GetCurrentContext();
5711 CHECK_NULL_VOID(pipeline);
5712 auto manager = pipeline->GetOverlayManager();
5713 CHECK_NULL_VOID(manager);
5714 pattern->SetSelectPopupMenuShowing(false);
5715 manager->DeleteMenu(id);
5716 };
5717 eventHub->SetOnDisappear(destructor);
5718
5719 WebPattern::InitSelectPopupMenuView(menu, callback, params, context->GetDipScale());
5720 menuWrapperPattern->RegisterMenuDisappearCallback([weak = WeakClaim(this), callback]() {
5721 auto pattern = weak.Upgrade();
5722 CHECK_NULL_VOID(pattern);
5723 callback->Cancel();
5724 pattern->SetSelectPopupMenuShowing(false);
5725 });
5726 auto offset = GetSelectPopupPostion(params->GetSelectMenuBound());
5727 TAG_LOGI(AceLogTag::ACE_WEB, "OnSelectPopupMenu offset:(%{public}f, %{public}f)", offset.GetX(), offset.GetY());
5728 selectPopupMenuShowing_ = true;
5729 overlayManager->ShowMenu(id, offset, menu);
5730 }
5731
NotifyForNextTouchEvent()5732 void WebPattern::NotifyForNextTouchEvent()
5733 {
5734 CHECK_NULL_VOID(delegate_);
5735 delegate_->NotifyForNextTouchEvent();
5736 }
5737
InitTouchEventListener()5738 void WebPattern::InitTouchEventListener()
5739 {
5740 TAG_LOGD(AceLogTag::ACE_WEB, "WebPattern::InitTouchEventListener");
5741 if (touchEventListener_) {
5742 return;
5743 }
5744 touchEventListener_ = std::make_shared<TouchEventListener>();
5745 touchEventListener_->SetPatternToListener(AceType::WeakClaim(this));
5746
5747 auto host = GetHost();
5748 CHECK_NULL_VOID(host);
5749 auto context = host->GetContext();
5750 CHECK_NULL_VOID(context);
5751
5752 context->RegisterTouchEventListener(touchEventListener_);
5753 }
5754
UninitTouchEventListener()5755 void WebPattern::UninitTouchEventListener()
5756 {
5757 TAG_LOGD(AceLogTag::ACE_WEB, "WebPattern::UninitTouchEventListener");
5758 touchEventListener_ = nullptr;
5759
5760 auto host = GetHost();
5761 CHECK_NULL_VOID(host);
5762 auto context = host->GetContext();
5763 CHECK_NULL_VOID(context);
5764 context->UnregisterTouchEventListener(AceType::WeakClaim(this));
5765 }
5766
OnDateTimeChooserPopup(std::shared_ptr<OHOS::NWeb::NWebDateTimeChooser> chooser,const std::vector<std::shared_ptr<OHOS::NWeb::NWebDateTimeSuggestion>> & suggestions,std::shared_ptr<NWeb::NWebDateTimeChooserCallback> callback)5767 void WebPattern::OnDateTimeChooserPopup(std::shared_ptr<OHOS::NWeb::NWebDateTimeChooser> chooser,
5768 const std::vector<std::shared_ptr<OHOS::NWeb::NWebDateTimeSuggestion>>& suggestions,
5769 std::shared_ptr<NWeb::NWebDateTimeChooserCallback> callback)
5770 {
5771 if (!chooser) {
5772 return;
5773 }
5774
5775 bool result = false;
5776 if (suggestions.size() != 0) {
5777 result = ShowDateTimeSuggestionDialog(chooser, suggestions, callback);
5778 } else if (chooser->GetType() == NWeb::DTC_TIME) {
5779 result = ShowTimeDialog(chooser, suggestions, callback);
5780 } else {
5781 result = ShowDateTimeDialog(chooser, suggestions, callback);
5782 }
5783 if (!result) {
5784 callback->Continue(false, OHOS::NWeb::DateTime());
5785 }
5786 }
5787
GetDialogProperties(const RefPtr<DialogTheme> & theme)5788 DialogProperties WebPattern::GetDialogProperties(const RefPtr<DialogTheme>& theme)
5789 {
5790 DialogProperties properties;
5791 if (GetWebInfoType() == WebInfoType::TYPE_MOBILE) {
5792 properties.alignment = DialogAlignment::BOTTOM;
5793 } else {
5794 properties.alignment = DialogAlignment::CENTER;
5795 }
5796 properties.customStyle = false;
5797 properties.offset = DimensionOffset(Offset(0, -theme->GetMarginBottom().ConvertToPx()));
5798 return properties;
5799 }
5800
ShowDateTimeDialog(std::shared_ptr<OHOS::NWeb::NWebDateTimeChooser> chooser,const std::vector<std::shared_ptr<OHOS::NWeb::NWebDateTimeSuggestion>> & suggestions,std::shared_ptr<NWeb::NWebDateTimeChooserCallback> callback)5801 bool WebPattern::ShowDateTimeDialog(std::shared_ptr<OHOS::NWeb::NWebDateTimeChooser> chooser,
5802 const std::vector<std::shared_ptr<OHOS::NWeb::NWebDateTimeSuggestion>>& suggestions,
5803 std::shared_ptr<NWeb::NWebDateTimeChooserCallback> callback)
5804 {
5805 auto container = Container::Current();
5806 CHECK_NULL_RETURN(container, false);
5807 auto pipelineContext = AccessibilityManager::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
5808 CHECK_NULL_RETURN(pipelineContext, false);
5809 auto executor = pipelineContext->GetTaskExecutor();
5810 CHECK_NULL_RETURN(executor, false);
5811 auto context = AccessibilityManager::DynamicCast<NG::PipelineContext>(pipelineContext);
5812 auto overlayManager = context ? context->GetOverlayManager() : nullptr;
5813 CHECK_NULL_RETURN(overlayManager, false);
5814 auto theme = pipelineContext->GetTheme<DialogTheme>();
5815 CHECK_NULL_RETURN(theme, false);
5816 NG::DatePickerSettingData settingData;
5817 settingData.isLunar = false;
5818 settingData.showTime = chooser->GetType() == NWeb::DTC_DATETIME_LOCAL;
5819 settingData.useMilitary = true;
5820 DialogProperties properties = GetDialogProperties(theme);
5821 std::map<std::string, PickerDate> datePickerProperty;
5822 std::map<std::string, PickerTime> timePickerProperty;
5823 OHOS::NWeb::DateTime minimum = chooser->GetMinimum();
5824 OHOS::NWeb::DateTime maximum = chooser->GetMaximum();
5825 OHOS::NWeb::DateTime dialogValue = chooser->GetDialogValue();
5826 settingData.datePickerProperty["start"] = PickerDate(minimum.year, minimum.month + 1, minimum.day);
5827 settingData.datePickerProperty["end"] = PickerDate(maximum.year, maximum.month + 1, maximum.day);
5828 if (chooser->GetHasSelected()) {
5829 int32_t day = (dialogValue.day == 0) ? 1 : dialogValue.day;
5830 settingData.datePickerProperty["selected"] = PickerDate(dialogValue.year, dialogValue.month + 1, day);
5831 }
5832 std::map<std::string, NG::DialogEvent> dialogEvent;
5833 std::map<std::string, NG::DialogGestureEvent> dialogCancelEvent;
5834 dialogEvent["acceptId"] = [callback](const std::string& info) {
5835 OHOS::NWeb::DateTime result;
5836 bool success = ParseDateTimeJson(info, result);
5837 callback->Continue(success, result);
5838 };
5839 dialogCancelEvent["cancelId"] =
5840 [callback](const GestureEvent&) { callback->Continue(false, OHOS::NWeb::DateTime()); };
5841 overlayManager->RegisterOnHideDialog([callback] { callback->Continue(false, OHOS::NWeb::DateTime()); });
5842 executor->PostTask(
5843 [properties, settingData, dialogEvent, dialogCancelEvent, weak = WeakPtr<NG::OverlayManager>(overlayManager)] {
5844 auto overlayManager = weak.Upgrade();
5845 CHECK_NULL_VOID(overlayManager);
5846 overlayManager->ShowDateDialog(properties, settingData, dialogEvent, dialogCancelEvent);
5847 },
5848 TaskExecutor::TaskType::UI, "ArkUIWebShowDateDialog");
5849 return true;
5850 }
5851
ShowTimeDialog(std::shared_ptr<OHOS::NWeb::NWebDateTimeChooser> chooser,const std::vector<std::shared_ptr<OHOS::NWeb::NWebDateTimeSuggestion>> & suggestions,std::shared_ptr<NWeb::NWebDateTimeChooserCallback> callback)5852 bool WebPattern::ShowTimeDialog(std::shared_ptr<OHOS::NWeb::NWebDateTimeChooser> chooser,
5853 const std::vector<std::shared_ptr<OHOS::NWeb::NWebDateTimeSuggestion>>& suggestions,
5854 std::shared_ptr<NWeb::NWebDateTimeChooserCallback> callback)
5855 {
5856 auto container = Container::Current();
5857 CHECK_NULL_RETURN(container, false);
5858 auto pipelineContext = AccessibilityManager::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
5859 CHECK_NULL_RETURN(pipelineContext, false);
5860 auto executor = pipelineContext->GetTaskExecutor();
5861 CHECK_NULL_RETURN(executor, false);
5862 auto theme = pipelineContext->GetTheme<DialogTheme>();
5863 CHECK_NULL_RETURN(theme, false);
5864 auto context = AccessibilityManager::DynamicCast<NG::PipelineContext>(pipelineContext);
5865 auto overlayManager = context ? context->GetOverlayManager() : nullptr;
5866 CHECK_NULL_RETURN(overlayManager, false);
5867 NG::TimePickerSettingData settingData;
5868 settingData.isUseMilitaryTime = true;
5869 DialogProperties properties = GetDialogProperties(theme);
5870 std::map<std::string, PickerTime> timePickerProperty;
5871 OHOS::NWeb::DateTime minimum = chooser->GetMinimum();
5872 OHOS::NWeb::DateTime maximum = chooser->GetMaximum();
5873 OHOS::NWeb::DateTime dialogValue = chooser->GetDialogValue();
5874 timePickerProperty["start"] = PickerTime(minimum.hour, minimum.minute, minimum.second);
5875 timePickerProperty["selected"] = PickerTime(maximum.hour, maximum.minute, maximum.second);
5876 if (chooser->GetHasSelected()) {
5877 timePickerProperty["selected"] = PickerTime(dialogValue.hour, dialogValue.minute, dialogValue.second);
5878 } else {
5879 auto timeOfNow = GetTimeOfNow();
5880 timePickerProperty["selected"] =
5881 PickerTime(timeOfNow.hour24_, timeOfNow.minute_, timeOfNow.second_);
5882 }
5883 std::map<std::string, NG::DialogEvent> dialogEvent;
5884 std::map<std::string, NG::DialogGestureEvent> dialogCancelEvent;
5885 dialogEvent["acceptId"] = [callback](const std::string& info) {
5886 OHOS::NWeb::DateTime result;
5887 bool success = ParseDateTimeJson(info, result);
5888 callback->Continue(success, result);
5889 };
5890 dialogCancelEvent["cancelId"] =
5891 [callback](const GestureEvent&) { callback->Continue(false, OHOS::NWeb::DateTime()); };
5892 overlayManager->RegisterOnHideDialog([callback] { callback->Continue(false, OHOS::NWeb::DateTime()); });
5893 executor->PostTask(
5894 [properties, settingData, timePickerProperty, dialogEvent, dialogCancelEvent,
5895 weak = WeakPtr<NG::OverlayManager>(overlayManager)] {
5896 auto overlayManager = weak.Upgrade();
5897 CHECK_NULL_VOID(overlayManager);
5898 overlayManager->ShowTimeDialog(properties, settingData, timePickerProperty, dialogEvent, dialogCancelEvent);
5899 },
5900 TaskExecutor::TaskType::UI, "ArkUIWebShowTimeDialog");
5901 return true;
5902 }
5903
ShowDateTimeSuggestionDialog(std::shared_ptr<OHOS::NWeb::NWebDateTimeChooser> chooser,const std::vector<std::shared_ptr<OHOS::NWeb::NWebDateTimeSuggestion>> & suggestions,std::shared_ptr<NWeb::NWebDateTimeChooserCallback> callback)5904 bool WebPattern::ShowDateTimeSuggestionDialog(std::shared_ptr<OHOS::NWeb::NWebDateTimeChooser> chooser,
5905 const std::vector<std::shared_ptr<OHOS::NWeb::NWebDateTimeSuggestion>>& suggestions,
5906 std::shared_ptr<NWeb::NWebDateTimeChooserCallback> callback)
5907 {
5908 auto container = Container::Current();
5909 CHECK_NULL_RETURN(container, false);
5910 auto pipelineContext = AccessibilityManager::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
5911 CHECK_NULL_RETURN(pipelineContext, false);
5912 auto executor = pipelineContext->GetTaskExecutor();
5913 CHECK_NULL_RETURN(executor, false);
5914 auto theme = pipelineContext->GetTheme<DialogTheme>();
5915 CHECK_NULL_RETURN(theme, false);
5916 auto context = AccessibilityManager::DynamicCast<NG::PipelineContext>(pipelineContext);
5917 auto overlayManager = context ? context->GetOverlayManager() : nullptr;
5918 CHECK_NULL_RETURN(overlayManager, false);
5919 NG::TextPickerSettingData settingData;
5920 if (memset_s(&settingData, sizeof(NG::TextPickerSettingData), 0, sizeof(NG::TextPickerSettingData)) != EOK) {
5921 return false;
5922 }
5923 std::map<std::string, OHOS::NWeb::DateTime> suggestionMap;
5924 for (size_t i = 0; i < suggestions.size(); i++) {
5925 settingData.rangeVector.push_back({ "", suggestions[i]->GetLocalizedValue() });
5926 settingData.values.push_back(suggestions[i]->GetLocalizedValue());
5927 suggestionMap.emplace(std::make_pair(suggestions[i]->GetLocalizedValue(), suggestions[i]->GetValue()));
5928 }
5929 settingData.columnKind = NG::TEXT;
5930 settingData.selected = chooser->GetSuggestionIndex();
5931 DialogProperties properties = GetDialogProperties(theme);
5932 std::map<std::string, NG::DialogTextEvent> dialogEvent;
5933 std::map<std::string, NG::DialogGestureEvent> dialogCancelEvent;
5934 dialogEvent["acceptId"] = [suggestionMap, callback](const std::string& info) {
5935 std::string value = ParseTextJsonValue(info);
5936 if (suggestionMap.find(value) != suggestionMap.end()) {
5937 callback->Continue(true, suggestionMap.at(value));
5938 } else {
5939 callback->Continue(false, OHOS::NWeb::DateTime());
5940 }
5941 };
5942 dialogCancelEvent["cancelId"] =
5943 [callback](const GestureEvent&) { callback->Continue(false, OHOS::NWeb::DateTime()); };
5944 overlayManager->RegisterOnHideDialog([callback] { callback->Continue(false, OHOS::NWeb::DateTime()); });
5945 executor->PostTask(
5946 [properties, settingData, dialogEvent, dialogCancelEvent,
5947 weak = WeakPtr<NG::OverlayManager>(overlayManager)] {
5948 auto overlayManager = weak.Upgrade();
5949 CHECK_NULL_VOID(overlayManager);
5950 overlayManager->ShowTextDialog(properties, settingData, dialogEvent, dialogCancelEvent);
5951 },
5952 TaskExecutor::TaskType::UI, "ArkUIWebShowTextDialog");
5953 return true;
5954 }
5955
OnDateTimeChooserClose()5956 void WebPattern::OnDateTimeChooserClose() {}
5957
InitSelectPopupMenuViewOption(const std::vector<RefPtr<FrameNode>> & options,const std::shared_ptr<OHOS::NWeb::NWebSelectPopupMenuCallback> & callback,const std::shared_ptr<OHOS::NWeb::NWebSelectPopupMenuParam> & params,const double & dipScale)5958 void WebPattern::InitSelectPopupMenuViewOption(const std::vector<RefPtr<FrameNode>>& options,
5959 const std::shared_ptr<OHOS::NWeb::NWebSelectPopupMenuCallback>& callback,
5960 const std::shared_ptr<OHOS::NWeb::NWebSelectPopupMenuParam>& params,
5961 const double& dipScale)
5962 {
5963 int32_t optionIndex = -1;
5964 int32_t width = params->GetSelectMenuBound() ? params->GetSelectMenuBound()->GetWidth() : 0;
5965 auto items = params->GetMenuItems();
5966 int32_t selectedIndex = params->GetSelectedItem();
5967 TAG_LOGD(AceLogTag::ACE_WEB, "InitSelectPopupMenuViewOption selectedIndex:%{public}d", selectedIndex);
5968
5969 for (auto &&option : options) {
5970 optionIndex++;
5971 CHECK_NULL_VOID(option);
5972 auto optionPattern = option->GetPattern<MenuItemPattern>();
5973 CHECK_NULL_VOID(optionPattern);
5974 auto optionPaintProperty = option->GetPaintProperty<MenuItemPaintProperty>();
5975 CHECK_NULL_VOID(optionPaintProperty);
5976 optionPaintProperty->SetIdealWidthForWeb(width - OPTION_MARGIN.ConvertToPx());
5977 optionPattern->SetFontSize(Dimension(params->GetItemFontSize() * dipScale));
5978 if (selectedIndex == optionIndex) {
5979 optionPattern->SetFontColor(SELECTED_OPTION_FONT_COLOR);
5980 optionPattern->SetBgColor(SELECTED_OPTION_BACKGROUND_COLOR);
5981 optionPattern->UpdateNextNodeDivider(false);
5982 optionPaintProperty->UpdateNeedDivider(false);
5983 }
5984 auto hub = option->GetOrCreateEventHub<MenuItemEventHub>();
5985 CHECK_NULL_VOID(hub);
5986 if (optionIndex >= 0 && static_cast<uint32_t>(optionIndex) < items.size()) {
5987 hub->SetEnabled(items[optionIndex]->GetIsEnabled());
5988 auto focusHub = option->GetFocusHub();
5989 if (focusHub) {
5990 focusHub->SetEnabled(items[optionIndex]->GetIsEnabled());
5991 }
5992 }
5993 auto selectCallback = [callback](int32_t index) {
5994 std::vector<int32_t> indices { static_cast<int32_t>(index) };
5995 callback->Continue(indices);
5996 };
5997 hub->SetOnSelect(std::move(selectCallback));
5998 option->MarkModifyDone();
5999 }
6000 }
6001
InitSelectPopupMenuView(RefPtr<FrameNode> & menuWrapper,std::shared_ptr<OHOS::NWeb::NWebSelectPopupMenuCallback> callback,std::shared_ptr<OHOS::NWeb::NWebSelectPopupMenuParam> params,const double & dipScale)6002 void WebPattern::InitSelectPopupMenuView(RefPtr<FrameNode>& menuWrapper,
6003 std::shared_ptr<OHOS::NWeb::NWebSelectPopupMenuCallback> callback,
6004 std::shared_ptr<OHOS::NWeb::NWebSelectPopupMenuParam> params,
6005 const double& dipScale)
6006 {
6007 auto menu = AceType::DynamicCast<FrameNode>(menuWrapper->GetChildAtIndex(0));
6008 CHECK_NULL_VOID(menu);
6009 auto menuPattern = menu->GetPattern<MenuPattern>();
6010 CHECK_NULL_VOID(menuPattern);
6011
6012 InitSelectPopupMenuViewOption(menuPattern->GetOptions(), callback, params, dipScale);
6013 }
6014
GetSelectPopupPostion(std::shared_ptr<OHOS::NWeb::NWebSelectMenuBound> bound)6015 OffsetF WebPattern::GetSelectPopupPostion(std::shared_ptr<OHOS::NWeb::NWebSelectMenuBound> bound)
6016 {
6017 auto offset = GetCoordinatePoint().value_or(OffsetF());
6018 if (bound) {
6019 offset.AddX(bound->GetX());
6020 offset.AddY(bound->GetY() + bound->GetHeight());
6021 }
6022 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
6023 offset.AddX(-CALIBERATE_X.ConvertToPx());
6024 }
6025 return offset;
6026 }
6027
UpdateLocale()6028 void WebPattern::UpdateLocale()
6029 {
6030 CHECK_NULL_VOID(delegate_);
6031 delegate_->UpdateLocale();
6032 }
6033
OnWindowShow()6034 void WebPattern::OnWindowShow()
6035 {
6036 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::OnWindowShow WebId : %{public}d", GetWebId());
6037 CHECK_NULL_VOID(delegate_);
6038 delegate_->OnRenderToForeground();
6039 delegate_->OnOnlineRenderToForeground();
6040
6041 if (isWindowShow_ || !isVisible_) {
6042 return;
6043 }
6044
6045 auto host = GetHost();
6046 CHECK_NULL_VOID(host);
6047 auto layoutProperty = host->GetLayoutProperty();
6048 CHECK_NULL_VOID(layoutProperty);
6049 componentVisibility_ = layoutProperty->GetVisibility().value_or(VisibleType::GONE);
6050 // When the visibility of web component is invisible, the window notification is not processed
6051 if (componentVisibility_ == VisibleType::INVISIBLE) {
6052 ACE_SCOPED_TRACE("WebPattern::OnWindowShow visibility of web component is invisible, WebId %d", GetWebId());
6053 return;
6054 }
6055 delegate_->ShowWebView();
6056 SetActiveStatusInner(true);
6057 isWindowShow_ = true;
6058 }
6059
OnWindowHide()6060 void WebPattern::OnWindowHide()
6061 {
6062 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::OnWindowHide WebId : %{public}d", GetWebId());
6063 CHECK_NULL_VOID(delegate_);
6064 delegate_->OnRenderToBackground();
6065
6066 if (!isWindowShow_) {
6067 return;
6068 }
6069
6070 CHECK_NULL_VOID(delegate_);
6071 SetActiveStatusInner(false);
6072 delegate_->HideWebView();
6073 CloseContextSelectionMenu();
6074 needOnFocus_ = false;
6075 isWindowShow_ = false;
6076 }
6077
OnWindowSizeChanged(int32_t width,int32_t height,WindowSizeChangeReason type)6078 void WebPattern::OnWindowSizeChanged(int32_t width, int32_t height, WindowSizeChangeReason type)
6079 {
6080 CHECK_NULL_VOID(delegate_);
6081 TAG_LOGD(AceLogTag::ACE_WEB, "WindowSizeChangeReason type: %{public}d ", type);
6082 if (type == WindowSizeChangeReason::MAXIMIZE) {
6083 WindowMaximize();
6084 return;
6085 }
6086 AdjustRotationRenderFit(type);
6087 bool isSmoothDragResizeEnabled = delegate_->GetIsSmoothDragResizeEnabled();
6088 if (!isSmoothDragResizeEnabled) {
6089 return;
6090 }
6091 dragResizeTimerFlag_ = false;
6092 auto dragTime = std::chrono::high_resolution_clock::now().time_since_epoch();
6093 lastDragTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(dragTime).count();
6094 if (type == WindowSizeChangeReason::DRAG_START || type == WindowSizeChangeReason::DRAG ||
6095 type == WindowSizeChangeReason::SPLIT_DRAG_START || type == WindowSizeChangeReason::SPLIT_DRAG) {
6096 if (dragResizeTimerCount_ == 0) {
6097 DragResizeNoMoveTimer();
6098 }
6099 dragWindowFlag_ = true;
6100 delegate_->SetDragResizeStartFlag(true);
6101 WindowDrag(width, height);
6102 }
6103 if (type == WindowSizeChangeReason::DRAG_END || type == WindowSizeChangeReason::SPLIT_DRAG_END) {
6104 dragResizeTimerFlag_ = true;
6105 dragResizeTimerCount_ = 0;
6106 delegate_->SetDragResizeStartFlag(false);
6107 auto frameNode = GetHost();
6108 CHECK_NULL_VOID(frameNode);
6109 auto offset = Offset(GetCoordinatePoint()->GetX(), GetCoordinatePoint()->GetY());
6110 delegate_->SetBoundsOrResize(drawSize_, offset, false);
6111 delegate_->ResizeVisibleViewport(visibleViewportSize_, false);
6112 dragWindowFlag_ = false;
6113 lastHeight_ = 0;
6114 lastWidth_ = 0;
6115 }
6116 }
6117
DragResizeNoMoveTimer()6118 void WebPattern::DragResizeNoMoveTimer()
6119 {
6120 if (dragResizeTimerFlag_) {
6121 dragResizeTimerCount_ = 0;
6122 return;
6123 }
6124 dragResizeTimerCount_++;
6125 auto host = GetHost();
6126 CHECK_NULL_VOID(host);
6127 auto context = host->GetContext();
6128 CHECK_NULL_VOID(context);
6129 auto taskExecutor = context->GetTaskExecutor();
6130 CHECK_NULL_VOID(taskExecutor);
6131 auto time = std::chrono::high_resolution_clock::now().time_since_epoch();
6132 int nowTime = std::chrono::duration_cast<std::chrono::milliseconds>(time).count();
6133 int diff = nowTime - lastDragTime_;
6134 if (diff > DRAG_RESIZE_NO_MOVE_CHECK_TIME) {
6135 auto offset = Offset(GetCoordinatePoint()->GetX(), GetCoordinatePoint()->GetY());
6136 delegate_->SetDragResizeStartFlag(false);
6137 delegate_->SetBoundsOrResize(drawSize_, offset, false);
6138 delegate_->ResizeVisibleViewport(visibleViewportSize_, false);
6139 }
6140 taskExecutor->PostDelayedTask([weak = WeakClaim(this)] () {
6141 auto webPattern = weak.Upgrade();
6142 CHECK_NULL_VOID(webPattern);
6143 webPattern->DragResizeNoMoveTimer();
6144 },
6145 TaskExecutor::TaskType::UI, DRAG_RESIZE_DELAY_TIME, "ArkUIWebDraggingResizeDelay");
6146 }
6147
WindowDrag(int32_t width,int32_t height)6148 void WebPattern::WindowDrag(int32_t width, int32_t height)
6149 {
6150 if (delegate_) {
6151 if (lastHeight_ == 0 && lastWidth_ == 0) {
6152 lastHeight_ = height;
6153 lastWidth_ = width;
6154 }
6155 if (!GetPendingSizeStatus() && dragWindowFlag_) {
6156 int64_t pre_height = height - lastHeight_;
6157 int64_t pre_width = width - lastWidth_;
6158 if (pre_width == 0 && pre_height == 0) {
6159 delegate_->SetDragResizePreSize(pre_height, pre_width);
6160 return;
6161 }
6162 if (pre_height <= CHECK_PRE_SIZE && pre_height > 0) {
6163 pre_height = 0;
6164 }
6165 if (pre_width <= CHECK_PRE_SIZE && pre_width > 0) {
6166 pre_width = 0;
6167 }
6168 lastHeight_ = height;
6169 lastWidth_ = width;
6170 if (pre_width == 0 && pre_height == 0) {
6171 return;
6172 }
6173 delegate_->SetDragResizePreSize(pre_height * ADJUST_RATIO, pre_width * ADJUST_RATIO);
6174 }
6175 }
6176 }
6177
WindowMaximize()6178 void WebPattern::WindowMaximize()
6179 {
6180 if (!SystemProperties::GetWebDebugMaximizeResizeOptimize()) {
6181 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::WindowMaximize not enabled");
6182 return;
6183 }
6184 WebInfoType webInfoType = GetWebInfoType();
6185 if (webInfoType != WebInfoType::TYPE_2IN1) {
6186 return;
6187 }
6188 if (layoutMode_ != WebLayoutMode::NONE || renderMode_ != RenderMode::ASYNC_RENDER) {
6189 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::WindowMaximize not support");
6190 return;
6191 }
6192 if (!isAttachedToMainTree_ || !isVisible_) {
6193 return;
6194 }
6195 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::WindowMaximize, webId: %{public}d", GetWebId());
6196 if (renderContextForSurface_) {
6197 renderContextForSurface_->SetRenderFit(RenderFit::RESIZE_FILL);
6198 }
6199 if (delegate_) {
6200 delegate_->MaximizeResize();
6201 }
6202 }
6203
OnCompleteSwapWithNewSize()6204 void WebPattern::OnCompleteSwapWithNewSize()
6205 {
6206 if (!isInWindowDrag_ || !isWaiting_)
6207 return;
6208
6209 ACE_SCOPED_TRACE("WebPattern::OnCompleteSwapWithNewSize");
6210 isWaiting_ = false;
6211 }
6212
OnResizeNotWork()6213 void WebPattern::OnResizeNotWork()
6214 {
6215 if (!isInWindowDrag_ || !isWaiting_)
6216 return;
6217
6218 ACE_SCOPED_TRACE("WebPattern::OnResizeNotWork");
6219 isWaiting_ = false;
6220 }
6221
UpdateOnFocusTextField(bool isFocus)6222 void WebPattern::UpdateOnFocusTextField(bool isFocus)
6223 {
6224 auto host = GetHost();
6225 CHECK_NULL_VOID(host);
6226 auto context = PipelineContext::GetCurrentContext();
6227 CHECK_NULL_VOID(context);
6228 auto textFieldManager = DynamicCast<TextFieldManagerNG>(context->GetTextFieldManager());
6229 CHECK_NULL_VOID(textFieldManager);
6230 isFocus ? textFieldManager->SetOnFocusTextField(WeakClaim(this))
6231 : textFieldManager->ClearOnFocusTextField(host->GetId());
6232 }
6233
OnBackPressed()6234 bool WebPattern::OnBackPressed()
6235 {
6236 auto host = GetHost();
6237 CHECK_NULL_RETURN(host, false);
6238 TAG_LOGI(AceLogTag::ACE_WEB, "Web %{public}d receives back press event", host->GetId());
6239 if (IsVirtualKeyBoardShow()) {
6240 CloseSelectOverlay();
6241 SelectCancel();
6242 TAG_LOGI(AceLogTag::ACE_WEB, "Request close soft keyboard.");
6243 auto inputMethod = MiscServices::InputMethodController::GetInstance();
6244 CHECK_NULL_RETURN(inputMethod, false);
6245 inputMethod->HideTextInput();
6246 inputMethod->Close();
6247 CHECK_NULL_RETURN(delegate_, true);
6248 delegate_->CloseCustomKeyboard();
6249 delegate_->GestureBackBlur();
6250 return true;
6251 }
6252 return false;
6253 }
6254
OnBackPressedForFullScreen() const6255 bool WebPattern::OnBackPressedForFullScreen() const
6256 {
6257 if (!isFullScreen_) {
6258 return false;
6259 }
6260
6261 TAG_LOGI(AceLogTag::ACE_WEB, "FullScreenBackPressEvent Received");
6262 CHECK_NULL_RETURN(fullScreenExitHandler_, false);
6263 auto webFullScreenExitHandler = fullScreenExitHandler_->GetHandler();
6264 CHECK_NULL_RETURN(webFullScreenExitHandler, false);
6265 webFullScreenExitHandler->ExitFullScreen();
6266 return true;
6267 }
6268
SetFullScreenExitHandler(const std::shared_ptr<FullScreenEnterEvent> & fullScreenExitHandler)6269 void WebPattern::SetFullScreenExitHandler(const std::shared_ptr<FullScreenEnterEvent>& fullScreenExitHandler)
6270 {
6271 fullScreenExitHandler_ = fullScreenExitHandler;
6272 }
6273
OnInActive()6274 void WebPattern::OnInActive()
6275 {
6276 TAG_LOGI(AceLogTag::ACE_WEB,
6277 "WebPattern::OnInActive webId:%{public}d, isActive:%{public}d",
6278 GetWebId(), isActive_);
6279 SetActiveStatusInner(false);
6280 }
6281
OnActive()6282 void WebPattern::OnActive()
6283 {
6284 TAG_LOGI(AceLogTag::ACE_WEB,
6285 "WebPattern::OnActive webId:%{public}d, isActive:%{public}d",
6286 GetWebId(), isActive_);
6287 UpdateScrollBarWithBorderRadius();
6288 SetActiveStatusInner(true);
6289 }
6290
OnVisibleAreaChange(bool isVisible)6291 void WebPattern::OnVisibleAreaChange(bool isVisible)
6292 {
6293 bool isDialogNested = IsDialogNested();
6294 ACE_SCOPED_TRACE("WebPattern::OnVisibleAreaChange, webId: %d, isVisible: %d", GetWebId(), isVisible);
6295 TAG_LOGI(AceLogTag::ACE_WEB,
6296 "WebPattern::OnVisibleAreaChange webId:%{public}d, isVisible:%{public}d, old_isVisible:%{public}d, "
6297 "isVisibleActiveEnable:%{public}d, isDialogNested:%{public}d, isFocus:%{public}d",
6298 GetWebId(), isVisible, isVisible_, isVisibleActiveEnable_, isDialogNested, isFocus_);
6299 // pass isVisible value to arkweb directly without any judgment
6300 if (delegate_) {
6301 delegate_->SetVisibility(isVisible);
6302 }
6303
6304 if (isVisible_ == isVisible) {
6305 return;
6306 }
6307
6308 isVisible_ = isVisible;
6309 if (!isVisible_) {
6310 if (webSelectOverlay_) {
6311 webSelectOverlay_->UpdateSingleHandleVisible(false);
6312 }
6313 OnCursorChange(OHOS::NWeb::CursorType::CT_POINTER, nullptr);
6314 CloseSelectOverlay();
6315 if (IS_CALLING_FROM_M114() || (webSelectOverlay_ && !webSelectOverlay_->IsSingleHandle())) {
6316 SelectCancel();
6317 }
6318 DestroyAnalyzerOverlay();
6319 CloseDataDetectorMenu();
6320 OnTooltip("");
6321 isDragEndMenuShow_ = false;
6322 if (isVisibleActiveEnable_ && (!isDialogNested || !isFocus_)) {
6323 SetActiveStatusInner(false);
6324 }
6325 } else {
6326 if (isVisibleActiveEnable_) {
6327 SetActiveStatusInner(true);
6328 }
6329 }
6330 }
6331
GetDefaultBackgroundColor()6332 Color WebPattern::GetDefaultBackgroundColor()
6333 {
6334 auto darkMode = GetDarkModeValue(webData_ ? (WebDarkMode::Auto) : (WebDarkMode::Off));
6335 if (GetForceDarkAccessValue(false) &&
6336 (darkMode == WebDarkMode::On || ((darkMode == WebDarkMode::Auto) && (GetSystemColor() == Color::BLACK)))) {
6337 return Color::BLACK;
6338 } else {
6339 return Color::WHITE;
6340 }
6341 }
6342
UpdateBackgroundColorRightNow(int32_t color)6343 void WebPattern::UpdateBackgroundColorRightNow(int32_t color)
6344 {
6345 Color bkColor = Color(static_cast<uint32_t>(color));
6346 std::string debugBkgroundColor = GetWebDebugBackGroundColor();
6347 if (debugBkgroundColor != "none") {
6348 // debugBkgroundColor : #FFFFFFFF ARGB format
6349 bkColor = Color::ColorFromString(debugBkgroundColor);
6350 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::UpdateBackgroundColorRightNow, use debug background color," \
6351 " color=%{public}s, web id = %{public}d", bkColor.ToString().c_str(), GetWebId());
6352 }
6353
6354 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::UpdateBackgroundColorRightNow, color=%{public}s, web id = %{public}d",
6355 bkColor.ToString().c_str(), GetWebId());
6356 auto host = GetHost();
6357 CHECK_NULL_VOID(host);
6358 auto renderContext = host->GetRenderContext();
6359 CHECK_NULL_VOID(renderContext);
6360 renderContext->UpdateBackgroundColor(bkColor);
6361 CHECK_NULL_VOID(renderContextForSurface_);
6362 renderContextForSurface_->UpdateBackgroundColor(bkColor);
6363 }
6364
GetSystemColor() const6365 Color WebPattern::GetSystemColor() const
6366 {
6367 Color color = Color::WHITE;
6368 auto appMgrClient = std::make_shared<AppExecFwk::AppMgrClient>();
6369 CHECK_NULL_RETURN(appMgrClient, color);
6370 if (appMgrClient->ConnectAppMgrService()) {
6371 return color;
6372 }
6373 auto systemConfig = OHOS::AppExecFwk::Configuration();
6374 appMgrClient->GetConfiguration(systemConfig);
6375 auto colorMode = systemConfig.GetItem(OHOS::AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
6376 if (colorMode == OHOS::AppExecFwk::ConfigurationInner::COLOR_MODE_DARK) {
6377 return Color::BLACK;
6378 }
6379 if (colorMode == OHOS::AppExecFwk::ConfigurationInner::COLOR_MODE_LIGHT) {
6380 return Color::WHITE;
6381 }
6382 TAG_LOGW(AceLogTag::ACE_WEB, "no system color mode is found.");
6383 return color;
6384 }
6385
OnNotifyMemoryLevel(int32_t level)6386 void WebPattern::OnNotifyMemoryLevel(int32_t level)
6387 {
6388 if (!isMemoryLevelEnable_) {
6389 return;
6390 }
6391 CHECK_NULL_VOID(delegate_);
6392 delegate_->NotifyMemoryLevel(level);
6393 }
6394
GetWebId()6395 int WebPattern::GetWebId()
6396 {
6397 if (delegate_) {
6398 return delegate_->GetWebId();
6399 }
6400 return -1;
6401 }
6402
HandleScroll(float offset,int32_t source,NestedState state,float velocity)6403 ScrollResult WebPattern::HandleScroll(float offset, int32_t source, NestedState state, float velocity)
6404 {
6405 // If no parent object is specified, the nearest nested scrollable parent is used by default.
6406 return HandleScroll(GetNestedScrollParent(), offset, source, state);
6407 }
6408
HandleScroll(RefPtr<NestableScrollContainer> parent,float offset,int32_t source,NestedState state)6409 ScrollResult WebPattern::HandleScroll(RefPtr<NestableScrollContainer> parent, float offset,
6410 int32_t source, NestedState state)
6411 {
6412 TAG_LOGD(AceLogTag::ACE_WEB,
6413 "WebPattern::HandleScroll scroll direction: %{public}d, find parent component: %{public}d",
6414 expectedScrollAxis_,
6415 (parent != nullptr));
6416 if (parent) {
6417 if (isTouchpadSliding_) {
6418 source = SCROLL_FROM_UPDATE;
6419 } else {
6420 source = isMouseEvent_ ? SCROLL_FROM_AXIS : source;
6421 }
6422 return parent->HandleScroll(offset, source, state);
6423 }
6424 return { 0.0f, false };
6425 }
6426
HandleScrollVelocity(float velocity,const RefPtr<NestableScrollContainer> & child)6427 bool WebPattern::HandleScrollVelocity(float velocity, const RefPtr<NestableScrollContainer>& child)
6428 {
6429 // If no parent object is specified, the nearest nested scrollable parent is used by default.
6430 return HandleScrollVelocity(GetNestedScrollParent(), velocity);
6431 }
6432
HandleScrollVelocity(RefPtr<NestableScrollContainer> parent,float velocity)6433 bool WebPattern::HandleScrollVelocity(RefPtr<NestableScrollContainer> parent, float velocity)
6434 {
6435 CHECK_NULL_RETURN(parent, false);
6436 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::HandleScrollVelocity, to parent scroll velocity=%{public}f", velocity);
6437 if (parent->HandleScrollVelocity(velocity)) {
6438 OnParentScrollDragEndRecursive(parent);
6439 return true;
6440 }
6441 return false;
6442 }
6443
OnScrollStartRecursive(WeakPtr<NestableScrollContainer> child,float position,float velocity)6444 void WebPattern::OnScrollStartRecursive(WeakPtr<NestableScrollContainer> child, float position, float velocity)
6445 {
6446 // If only one position value is passed, it will be notified to the nearest nested scrollable parent.
6447 OnScrollStartRecursive(position);
6448 }
6449
OnScrollStartRecursive(float position)6450 void WebPattern::OnScrollStartRecursive(float position)
6451 {
6452 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::OnScrollStartRecursive");
6453 SetIsNestedInterrupt(false);
6454 isFirstFlingScrollVelocity_ = true;
6455 isScrollStarted_ = true;
6456 isDragEnd_ = false;
6457 auto it = parentsMap_.find(expectedScrollAxis_);
6458 CHECK_EQUAL_VOID(it, parentsMap_.end());
6459 auto parent = it->second.Upgrade();
6460 if (parent) {
6461 parent->OnScrollStartRecursive(WeakClaim(this), position);
6462 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::OnScrollStartRecursive parent OnScrollStartRecursive");
6463 }
6464 }
6465
OnAttachToBuilderNode(NodeStatus nodeStatus)6466 void WebPattern::OnAttachToBuilderNode(NodeStatus nodeStatus)
6467 {
6468 TAG_LOGD(AceLogTag::ACE_WEB, "WebPattern::OnAttachToBuilderNode");
6469 if (nodeStatus != NodeStatus::NORMAL_NODE) {
6470 InitInOfflineMode();
6471 }
6472 }
6473
OnScrollEndRecursive(const std::optional<float> & velocity)6474 void WebPattern::OnScrollEndRecursive(const std::optional<float>& velocity)
6475 {
6476 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::OnScrollEndRecursive");
6477 CHECK_EQUAL_VOID(isScrollStarted_, false);
6478 auto it = parentsMap_.find(expectedScrollAxis_);
6479 if (parentsMap_.find(expectedScrollAxis_) != parentsMap_.end()) {
6480 auto parent = it->second.Upgrade();
6481 if (parent) {
6482 OnParentScrollDragEndRecursive(parent);
6483 parent->OnScrollEndRecursive(std::nullopt);
6484 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::OnScrollEndRecursive parent OnScrollEndRecursive");
6485 }
6486 }
6487 isScrollStarted_ = false;
6488 SetIsNestedInterrupt(false);
6489 }
6490
OnOverScrollFlingVelocity(float xVelocity,float yVelocity,bool isFling)6491 void WebPattern::OnOverScrollFlingVelocity(float xVelocity, float yVelocity, bool isFling)
6492 {
6493 float velocity = (expectedScrollAxis_ == Axis::HORIZONTAL) ? xVelocity : yVelocity;
6494 OnOverScrollFlingVelocityHandler(velocity, isFling);
6495 }
6496
OnOverScrollFlingVelocityHandler(float velocity,bool isFling)6497 void WebPattern::OnOverScrollFlingVelocityHandler(float velocity, bool isFling)
6498 {
6499 auto it = parentsMap_.find(expectedScrollAxis_);
6500 CHECK_EQUAL_VOID(it, parentsMap_.end());
6501 auto parent = it->second;
6502 ScrollResult result = { 0.f, true };
6503 auto remain = 0.f;
6504 if (!isFling) {
6505 if (scrollState_) {
6506 if (CheckOverParentScroll(velocity, NestedScrollMode::SELF_FIRST)) {
6507 result = HandleScroll(parent.Upgrade(), -velocity, SCROLL_FROM_UPDATE, NestedState::CHILD_SCROLL);
6508 remain = result.remain;
6509 } else if (CheckOverParentScroll(velocity, NestedScrollMode::PARENT_FIRST)) {
6510 remain = -velocity;
6511 }
6512 if (!NearZero(remain)) {
6513 HandleScroll(parent.Upgrade(), remain, SCROLL_FROM_UPDATE, NestedState::CHILD_OVER_SCROLL);
6514 }
6515 }
6516 } else {
6517 if (CheckParentScroll(velocity, NestedScrollMode::SELF_FIRST)) {
6518 if (isFirstFlingScrollVelocity_) {
6519 HandleScrollVelocity(parent.Upgrade(), velocity);
6520 isFirstFlingScrollVelocity_ = false;
6521 }
6522 }
6523 }
6524 }
6525
OnScrollState(bool scrollState)6526 void WebPattern::OnScrollState(bool scrollState)
6527 {
6528 scrollState_ = scrollState;
6529 if (!scrollState) {
6530 OnScrollEndRecursive(std::nullopt);
6531 }
6532 }
6533
OnScrollStart(const float x,const float y)6534 void WebPattern::OnScrollStart(const float x, const float y)
6535 {
6536 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::OnScrollStart x=%{public}f, y=%{public}f", x, y);
6537 scrollState_ = true;
6538 GetParentAxis();
6539 expectedScrollAxis_ =(abs(x) > abs(y) ? Axis::HORIZONTAL : Axis::VERTICAL);
6540 OnScrollStartRecursive(0.0);
6541 if (imageAnalyzerManager_) {
6542 imageAnalyzerManager_->UpdateOverlayStatus(
6543 false,
6544 0,
6545 0,
6546 0,
6547 0);
6548 }
6549 }
6550
SetLayoutMode(WebLayoutMode mode)6551 void WebPattern::SetLayoutMode(WebLayoutMode mode)
6552 {
6553 if (layoutMode_ == mode) {
6554 return;
6555 }
6556 layoutMode_ = mode;
6557 TAG_LOGI(AceLogTag::ACE_WEB, "layoutMode is: %{public}d.", layoutMode_);
6558 OnZoomAccessEnabledUpdate(GetZoomAccessEnabledValue(true));
6559 if (delegate_) {
6560 delegate_->UpdateLayoutMode(mode);
6561 }
6562 isLayoutModeChanged_ = true;
6563 auto frameNode = GetHost();
6564 CHECK_NULL_VOID(frameNode);
6565 frameNode->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT | PROPERTY_UPDATE_MEASURE | PROPERTY_UPDATE_RENDER);
6566 }
6567
SetRenderMode(RenderMode renderMode)6568 void WebPattern::SetRenderMode(RenderMode renderMode)
6569 {
6570 if (isRenderModeInit_) {
6571 TAG_LOGI(AceLogTag::ACE_WEB, "renderMode not allow to change.");
6572 return;
6573 }
6574 renderMode_ = renderMode;
6575 TAG_LOGI(AceLogTag::ACE_WEB, "renderMode is %{public}d", renderMode_);
6576 isRenderModeInit_ = true;
6577 }
6578
GetParentAxis()6579 void WebPattern::GetParentAxis()
6580 {
6581 auto parent = GetNestedScrollParent();
6582 if (parent) {
6583 axis_ = parent->GetAxis();
6584 parentsMap_ = { { axis_, parent } };
6585 auto oppositeParent = SearchParent(axis_ == Axis::HORIZONTAL ? Axis::VERTICAL : Axis::HORIZONTAL);
6586 if (oppositeParent) {
6587 parentsMap_.emplace(oppositeParent->GetAxis(), oppositeParent);
6588 }
6589 } else {
6590 auto verticalParent = SearchParent(Axis::VERTICAL);
6591 auto horizontalParent = SearchParent(Axis::HORIZONTAL);
6592 if (verticalParent) {
6593 parentsMap_.emplace(verticalParent->GetAxis(), verticalParent);
6594 }
6595 if (horizontalParent) {
6596 parentsMap_.emplace(horizontalParent->GetAxis(), horizontalParent);
6597 }
6598 }
6599 }
6600
SearchParent()6601 RefPtr<NestableScrollContainer> WebPattern::SearchParent()
6602 {
6603 return SearchParent(Axis::NONE);
6604 }
6605
SearchParent(Axis scrollAxis)6606 RefPtr<NestableScrollContainer> WebPattern::SearchParent(Axis scrollAxis)
6607 {
6608 auto host = GetHost();
6609 CHECK_NULL_RETURN(host, nullptr);
6610 for (auto parent = host->GetParent(); parent != nullptr; parent = parent->GetParent()) {
6611 RefPtr<FrameNode> frameNode = AceType::DynamicCast<FrameNode>(parent);
6612 if (!frameNode) {
6613 continue;
6614 }
6615 auto pattern = frameNode->GetPattern<NestableScrollContainer>();
6616 if (!pattern ||
6617 (!AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE) &&
6618 InstanceOf<RefreshPattern>(pattern))) {
6619 continue;
6620 }
6621 if (scrollAxis == Axis::NONE || scrollAxis == pattern->GetAxis()) {
6622 return pattern;
6623 }
6624 }
6625 return nullptr;
6626 }
6627
SetNestedScrollExt(const NestedScrollOptionsExt & nestedScroll)6628 void WebPattern::SetNestedScrollExt(const NestedScrollOptionsExt &nestedScroll)
6629 {
6630 NestedScrollOptions nestedOpt = {
6631 .forward = NestedScrollMode::SELF_FIRST,
6632 .backward = NestedScrollMode::SELF_FIRST,
6633 };
6634 if (nestedScroll.scrollUp == nestedScroll.scrollLeft) {
6635 nestedOpt.backward = nestedScroll.scrollUp;
6636 }
6637 if (nestedScroll.scrollDown == nestedScroll.scrollRight) {
6638 nestedOpt.forward = nestedScroll.scrollDown;
6639 }
6640 auto pattern = ViewStackProcessor::GetInstance()->GetMainFrameNodePattern<NestableScrollContainer>();
6641 if (pattern) {
6642 pattern->SetNestedScroll(nestedOpt);
6643 }
6644 TAG_LOGI(
6645 AceLogTag::ACE_WEB, "SetNestedScrollExt nestedScroll: %{public}s", nestedScroll.ToString().c_str());
6646 nestedScroll_ = nestedScroll;
6647 }
6648
IsDialogNested()6649 bool WebPattern::IsDialogNested()
6650 {
6651 auto host = GetHost();
6652 CHECK_NULL_RETURN(host, false);
6653 for (auto parent = host->GetParent(); parent != nullptr; parent = parent->GetParent()) {
6654 RefPtr<FrameNode> frameNode = AceType::DynamicCast<FrameNode>(parent);
6655 if (!frameNode) {
6656 continue;
6657 }
6658 if (frameNode->GetPattern<DialogPattern>()) {
6659 return true;
6660 }
6661 }
6662 return false;
6663 }
6664
OnRootLayerChanged(int width,int height)6665 void WebPattern::OnRootLayerChanged(int width, int height)
6666 {
6667 if ((rootLayerWidth_ == width) && (rootLayerHeight_ == height)) {
6668 return;
6669 }
6670 TAG_LOGI(AceLogTag::ACE_WEB, "OnRootLayerChanged width : %{public}d, height : %{public}d", width, height);
6671 rootLayerWidth_ = width;
6672 rootLayerHeight_ = height;
6673 if (layoutMode_ != WebLayoutMode::FIT_CONTENT) {
6674 return;
6675 }
6676 rootLayerChangeSize_ = Size(width, height);
6677 ReleaseResizeHold();
6678 }
6679
ReleaseResizeHold()6680 void WebPattern::ReleaseResizeHold()
6681 {
6682 if (layoutMode_ != WebLayoutMode::FIT_CONTENT) {
6683 return;
6684 }
6685 drawSize_.SetSize(rootLayerChangeSize_);
6686 auto frameNode = GetHost();
6687 CHECK_NULL_VOID(frameNode);
6688 frameNode->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT | PROPERTY_UPDATE_MEASURE | PROPERTY_UPDATE_RENDER);
6689 }
6690
OnNestedScroll(float & x,float & y,float & xVelocity,float & yVelocity,bool & isAvailable)6691 bool WebPattern::OnNestedScroll(float& x, float& y, float& xVelocity, float& yVelocity, bool& isAvailable)
6692 {
6693 isAvailable = true;
6694 // not a nested scrolling scene
6695 bool hasHorizontalParent = parentsMap_.find(Axis::HORIZONTAL) != parentsMap_.end();
6696 bool hasVerticalParent = parentsMap_.find(Axis::VERTICAL) != parentsMap_.end();
6697 if (!hasHorizontalParent && !hasVerticalParent) {
6698 return false;
6699 }
6700 float offset = y;
6701 float velocity = yVelocity;
6702 if (expectedScrollAxis_ == Axis::HORIZONTAL) {
6703 offset = x;
6704 velocity = xVelocity;
6705 if (isScrollStarted_) {
6706 y = 0.0f;
6707 yVelocity = 0.0f;
6708 }
6709 } else {
6710 if (isScrollStarted_) {
6711 x = 0.0f;
6712 xVelocity = 0.0f;
6713 }
6714 }
6715 bool isConsumed = offset != 0 ? FilterScrollEventHandleOffset(offset) : FilterScrollEventHandlevVlocity(velocity);
6716 return isConsumed;
6717 }
6718
FilterScrollEvent(const float x,const float y,const float xVelocity,const float yVelocity)6719 bool WebPattern::FilterScrollEvent(const float x, const float y, const float xVelocity, const float yVelocity)
6720 {
6721 float offset = expectedScrollAxis_ == Axis::HORIZONTAL ? x : y;
6722 float velocity = expectedScrollAxis_ == Axis::HORIZONTAL ? xVelocity : yVelocity;
6723 bool isConsumed = offset != 0 ? FilterScrollEventHandleOffset(offset) : FilterScrollEventHandlevVlocity(velocity);
6724 return isConsumed;
6725 }
6726
FilterScrollEventHandleOffset(float offset)6727 bool WebPattern::FilterScrollEventHandleOffset(float offset)
6728 {
6729 auto it = parentsMap_.find(expectedScrollAxis_);
6730 CHECK_EQUAL_RETURN(it, parentsMap_.end(), false);
6731 auto parent = it->second;
6732 if (parent.Upgrade() && !NearZero(offset)) {
6733 auto res = HandleScroll(parent.Upgrade(), offset, SCROLL_FROM_UPDATE, NestedState::CHILD_CHECK_OVER_SCROLL);
6734 if (NearZero(res.remain)) {
6735 return true;
6736 }
6737 offset = res.remain;
6738 }
6739 if (CheckParentScroll(offset, NestedScrollMode::PARENT_FIRST)) {
6740 auto result = HandleScroll(parent.Upgrade(), offset, SCROLL_FROM_UPDATE, NestedState::CHILD_SCROLL);
6741 CHECK_EQUAL_RETURN(isParentReachEdge_ && result.reachEdge, true, false);
6742 isParentReachEdge_ = result.reachEdge;
6743 CHECK_NULL_RETURN(delegate_, false);
6744 expectedScrollAxis_ == Axis::HORIZONTAL ? delegate_->ScrollByRefScreen(-result.remain, 0)
6745 : delegate_->ScrollByRefScreen(0, -result.remain);
6746 return true;
6747 } else if (CheckParentScroll(offset, NestedScrollMode::PARALLEL)) {
6748 HandleScroll(parent.Upgrade(), offset, SCROLL_FROM_UPDATE, NestedState::CHILD_SCROLL);
6749 } else if (CheckParentScroll(offset, NestedScrollMode::SELF_FIRST) && NestedScrollOutOfBoundary()) {
6750 HandleScroll(parent.Upgrade(), offset, SCROLL_FROM_UPDATE, NestedState::CHILD_OVER_SCROLL);
6751 return true;
6752 }
6753 return false;
6754 }
6755
CheckParentScroll(const float & directValue,const NestedScrollMode & scrollMode)6756 bool WebPattern::CheckParentScroll(const float &directValue, const NestedScrollMode &scrollMode)
6757 {
6758 auto nestedScroll = GetNestedScrollExt();
6759 return (directValue > 0 && nestedScroll.scrollUp == scrollMode &&
6760 expectedScrollAxis_ != Axis::HORIZONTAL) ||
6761 (directValue > 0 && nestedScroll.scrollLeft == scrollMode &&
6762 expectedScrollAxis_ == Axis::HORIZONTAL) ||
6763 (directValue < 0 && nestedScroll.scrollDown == scrollMode &&
6764 expectedScrollAxis_ != Axis::HORIZONTAL) ||
6765 (directValue < 0 && nestedScroll.scrollRight == scrollMode &&
6766 expectedScrollAxis_ == Axis::HORIZONTAL);
6767 }
6768
CheckOverParentScroll(const float & directValue,const NestedScrollMode & scrollMode)6769 bool WebPattern::CheckOverParentScroll(const float &directValue, const NestedScrollMode &scrollMode)
6770 {
6771 auto nestedScroll = GetNestedScrollExt();
6772 return (directValue < 0 && nestedScroll.scrollUp == scrollMode &&
6773 expectedScrollAxis_ != Axis::HORIZONTAL) ||
6774 (directValue < 0 && nestedScroll.scrollLeft == scrollMode &&
6775 expectedScrollAxis_ == Axis::HORIZONTAL) ||
6776 (directValue > 0 && nestedScroll.scrollDown == scrollMode &&
6777 expectedScrollAxis_ != Axis::HORIZONTAL) ||
6778 (directValue > 0 && nestedScroll.scrollRight == scrollMode &&
6779 expectedScrollAxis_ == Axis::HORIZONTAL);
6780 }
6781
FilterScrollEventHandlevVlocity(const float velocity)6782 bool WebPattern::FilterScrollEventHandlevVlocity(const float velocity)
6783 {
6784 auto it = parentsMap_.find(expectedScrollAxis_);
6785 CHECK_EQUAL_RETURN(it, parentsMap_.end(), false);
6786 auto parent = it->second;
6787 if (parent.Upgrade() && parent.Upgrade()->NestedScrollOutOfBoundary()) {
6788 return HandleScrollVelocity(parent.Upgrade(), velocity);
6789 }
6790 if (CheckParentScroll(velocity, NestedScrollMode::PARENT_FIRST)) {
6791 if (isParentReachEdge_) {
6792 return false;
6793 }
6794 return HandleScrollVelocity(parent.Upgrade(), velocity);
6795 } else if (CheckParentScroll(velocity, NestedScrollMode::PARALLEL)) {
6796 HandleScrollVelocity(parent.Upgrade(), velocity);
6797 }
6798 return false;
6799 }
6800
CheckAndSetWebNestedScrollExisted()6801 void WebPattern::CheckAndSetWebNestedScrollExisted()
6802 {
6803 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::CheckAndSetWebNestedScrollExisted");
6804 auto webBypassVsyncCondition = GetWebBypassVsyncCondition();
6805 bool isVsyncCondition = WebBypassVsyncCondition::SCROLLBY_FROM_ZERO_OFFSET == webBypassVsyncCondition;
6806 auto it = parentsMap_.find(Axis::VERTICAL);
6807 if (parentsMap_.find(Axis::VERTICAL) != parentsMap_.end()) {
6808 auto parent = it->second.Upgrade();
6809 if (parent) {
6810 TAG_LOGI(AceLogTag::ACE_WEB,
6811 "WebPattern::CheckAndSetWebNestedScrollExisted isVsyncCondition:%{public}d",
6812 isVsyncCondition);
6813 parent->SetWebNestedScrollExisted(isVsyncCondition);
6814 }
6815 }
6816
6817 it = parentsMap_.find(Axis::HORIZONTAL);
6818 if (parentsMap_.find(Axis::HORIZONTAL) != parentsMap_.end()) {
6819 auto parent = it->second.Upgrade();
6820 if (parent) {
6821 TAG_LOGI(AceLogTag::ACE_WEB,
6822 "WebPattern::CheckAndSetWebNestedScrollExisted isVsyncCondition:%{public}d",
6823 isVsyncCondition);
6824 parent->SetWebNestedScrollExisted(isVsyncCondition);
6825 }
6826 }
6827 }
6828
IsDefaultFocusNodeExist()6829 bool WebPattern::IsDefaultFocusNodeExist()
6830 {
6831 auto pipeline = PipelineContext::GetCurrentContext();
6832 CHECK_NULL_RETURN(pipeline, false);
6833 auto focusManager = pipeline->GetFocusManager();
6834 CHECK_NULL_RETURN(focusManager, false);
6835 auto focusView = focusManager->GetLastFocusView().Upgrade();
6836 CHECK_NULL_RETURN(focusView, false);
6837 auto focusHub = focusView->GetFocusHub();
6838 CHECK_NULL_RETURN(focusHub, false);
6839 bool result = focusHub->GetChildFocusNodeByType();
6840 return result;
6841 }
6842
InitSlideUpdateListener()6843 void WebPattern::InitSlideUpdateListener()
6844 {
6845 auto host = GetHost();
6846 CHECK_NULL_VOID(host);
6847 for (auto parent = host->GetParent(); parent != nullptr; parent = parent->GetParent()) {
6848 bool hasTargetParent =
6849 std::find(SYNC_RENDER_SLIDE.begin(), SYNC_RENDER_SLIDE.end(), parent->GetTag()) == SYNC_RENDER_SLIDE.end();
6850 if (hasTargetParent) {
6851 continue;
6852 }
6853 RefPtr<FrameNode> frameNode = AceType::DynamicCast<FrameNode>(parent);
6854 CHECK_NULL_VOID(frameNode);
6855 if (parent->GetTag() == V2::LIST_ETS_TAG) {
6856 auto pattern = frameNode->GetPattern<ListPattern>();
6857 CHECK_NULL_VOID(pattern);
6858 syncAxis_ = pattern->GetAxis();
6859 } else {
6860 auto pattern = frameNode->GetPattern<ScrollPattern>();
6861 CHECK_NULL_VOID(pattern);
6862 syncAxis_ = pattern->GetAxis();
6863 }
6864 CHECK_NULL_VOID(renderSurface_);
6865 renderSurface_->SetWebSlideAxis(syncAxis_);
6866 }
6867 }
6868
UpdateSlideOffset()6869 void WebPattern::UpdateSlideOffset()
6870 {
6871 switch (syncAxis_) {
6872 case Axis::HORIZONTAL:
6873 CalculateHorizontalDrawRect();
6874 break;
6875 case Axis::VERTICAL:
6876 CalculateVerticalDrawRect();
6877 break;
6878 default :
6879 break;
6880 }
6881 }
6882
CalculateHorizontalDrawRect()6883 void WebPattern::CalculateHorizontalDrawRect()
6884 {
6885 if (!GetCoordinatePoint().has_value()) {
6886 return;
6887 }
6888 fitContentOffset_ = OffsetF(GetCoordinatePoint()->GetX(), GetCoordinatePoint()->GetY());
6889 CHECK_NULL_VOID(renderSurface_);
6890 renderSurface_->SetWebOffset(fitContentOffset_.GetX());
6891 if (fitContentOffset_.GetX() >= 0) {
6892 if (isNeedReDrawRect_) {
6893 SetDrawRect(0, 0, ADJUST_WEB_DRAW_LENGTH + ADJUST_WEB_DRAW_LENGTH, drawRectHeight_);
6894 }
6895 isNeedReDrawRect_ = false;
6896 return;
6897 }
6898
6899 int32_t stepGear = (-fitContentOffset_.GetX()) / ADJUST_WEB_DRAW_LENGTH;
6900 int32_t width = ADJUST_WEB_DRAW_LENGTH * 2 + stepGear;
6901 int32_t height = std::min(static_cast<int32_t>(drawSize_.Height()), FIT_CONTENT_LIMIT_LENGTH);
6902 int32_t x = ADJUST_WEB_DRAW_LENGTH * stepGear;
6903 int32_t y = 0;
6904 renderSurface_->SetWebMessage({ x, 0 });
6905 TAG_LOGD(AceLogTag::ACE_WEB, "SetDrawRect x : %{public}d, y : %{public}d, width : %{public}d, height : %{public}d",
6906 x, y, width, height);
6907 SetDrawRect(x, y, width, height);
6908 isNeedReDrawRect_ = true;
6909 }
6910
CalculateVerticalDrawRect()6911 void WebPattern::CalculateVerticalDrawRect()
6912 {
6913 if (!GetCoordinatePoint().has_value()) {
6914 return;
6915 }
6916 fitContentOffset_ = OffsetF(GetCoordinatePoint()->GetX(), GetCoordinatePoint()->GetY());
6917 CHECK_NULL_VOID(renderSurface_);
6918 renderSurface_->SetWebOffset(fitContentOffset_.GetY());
6919 if (fitContentOffset_.GetY() >= 0) {
6920 if (isNeedReDrawRect_) {
6921 SetDrawRect(0, 0, drawRectWidth_, ADJUST_WEB_DRAW_LENGTH + ADJUST_WEB_DRAW_LENGTH);
6922 }
6923 isNeedReDrawRect_ = false;
6924 return;
6925 }
6926
6927 int32_t stepGear = (-fitContentOffset_.GetY()) / ADJUST_WEB_DRAW_LENGTH;
6928 int32_t width = std::min(static_cast<int32_t>(drawSize_.Width()), FIT_CONTENT_LIMIT_LENGTH);
6929 int32_t height = ADJUST_WEB_DRAW_LENGTH * 2 + stepGear;
6930 int32_t x = 0;
6931 int32_t y = ADJUST_WEB_DRAW_LENGTH * stepGear;
6932 renderSurface_->SetWebMessage({ 0, y });
6933 TAG_LOGD(AceLogTag::ACE_WEB, "SetDrawRect x : %{public}d, y : %{public}d, width : %{public}d, height : %{public}d",
6934 x, y, width, height);
6935 SetDrawRect(x, y, width, height);
6936 isNeedReDrawRect_ = true;
6937 }
6938
PostTaskToUI(const std::function<void ()> && task,const std::string & name) const6939 void WebPattern::PostTaskToUI(const std::function<void()>&& task, const std::string& name) const
6940 {
6941 CHECK_NULL_VOID(task);
6942 auto container = Container::Current();
6943 CHECK_NULL_VOID(container);
6944 auto pipelineContext = AccessibilityManager::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
6945 CHECK_NULL_VOID(pipelineContext);
6946 auto taskExecutor = pipelineContext->GetTaskExecutor();
6947 CHECK_NULL_VOID(taskExecutor);
6948 taskExecutor->PostTask(task, TaskExecutor::TaskType::UI, name);
6949 }
6950
SetDrawRect(int32_t x,int32_t y,int32_t width,int32_t height)6951 void WebPattern::SetDrawRect(int32_t x, int32_t y, int32_t width, int32_t height)
6952 {
6953 if ((drawRectWidth_ == width) && (drawRectHeight_ == height)) {
6954 return;
6955 }
6956 drawRectWidth_ = width;
6957 drawRectHeight_ = height;
6958 CHECK_NULL_VOID(delegate_);
6959 delegate_->SetDrawRect(x, y, width, height);
6960 }
6961
GetPendingSizeStatus()6962 bool WebPattern::GetPendingSizeStatus()
6963 {
6964 if (delegate_) {
6965 return delegate_->GetPendingSizeStatus();
6966 }
6967 return false;
6968 }
6969
CreateNodePaintMethod()6970 RefPtr<NodePaintMethod> WebPattern::CreateNodePaintMethod()
6971 {
6972 auto paint = MakeRefPtr<WebPaintMethod>(renderSurface_);
6973 return paint;
6974 }
6975
JavaScriptOnDocumentStart(const ScriptItems & scriptItems)6976 void WebPattern::JavaScriptOnDocumentStart(const ScriptItems& scriptItems)
6977 {
6978 onDocumentStartScriptItems_ = std::make_optional<ScriptItems>(scriptItems);
6979 onDocumentStartScriptItemsByOrder_ = std::nullopt;
6980 if (delegate_) {
6981 UpdateJavaScriptOnDocumentStart();
6982 delegate_->JavaScriptOnDocumentStart();
6983 }
6984 }
6985
JavaScriptOnDocumentStartByOrder(const ScriptItems & scriptItems,const ScriptItemsByOrder & scriptItemsByOrder)6986 void WebPattern::JavaScriptOnDocumentStartByOrder(const ScriptItems& scriptItems,
6987 const ScriptItemsByOrder& scriptItemsByOrder)
6988 {
6989 onDocumentStartScriptItems_ = std::make_optional<ScriptItems>(scriptItems);
6990 onDocumentStartScriptItemsByOrder_ = std::make_optional<ScriptItemsByOrder>(scriptItemsByOrder);
6991 if (delegate_) {
6992 UpdateJavaScriptOnDocumentStartByOrder();
6993 delegate_->JavaScriptOnDocumentStartByOrder();
6994 }
6995 }
6996
JavaScriptOnDocumentEndByOrder(const ScriptItems & scriptItems,const ScriptItemsByOrder & scriptItemsByOrder)6997 void WebPattern::JavaScriptOnDocumentEndByOrder(const ScriptItems& scriptItems,
6998 const ScriptItemsByOrder& scriptItemsByOrder)
6999 {
7000 onDocumentEndScriptItems_ = std::make_optional<ScriptItems>(scriptItems);
7001 onDocumentEndScriptItemsByOrder_ = std::make_optional<ScriptItemsByOrder>(scriptItemsByOrder);
7002 EventRecorder::Get().FillWebJsCode(onDocumentEndScriptItems_);
7003 if (delegate_) {
7004 UpdateJavaScriptOnDocumentEndByOrder();
7005 delegate_->JavaScriptOnDocumentEndByOrder();
7006 }
7007 }
7008
JavaScriptOnHeadReadyByOrder(const ScriptItems & scriptItems,const ScriptItemsByOrder & scriptItemsByOrder)7009 void WebPattern::JavaScriptOnHeadReadyByOrder(const ScriptItems& scriptItems,
7010 const ScriptItemsByOrder& scriptItemsByOrder)
7011 {
7012 onHeadReadyScriptItems_ = std::make_optional<ScriptItems>(scriptItems);
7013 onHeadReadyScriptItemsByOrder_ = std::make_optional<ScriptItemsByOrder>(scriptItemsByOrder);
7014 if (delegate_) {
7015 UpdateJavaScriptOnHeadReadyByOrder();
7016 delegate_->JavaScriptOnHeadReadyByOrder();
7017 }
7018 }
7019
JavaScriptOnDocumentEnd(const ScriptItems & scriptItems)7020 void WebPattern::JavaScriptOnDocumentEnd(const ScriptItems& scriptItems)
7021 {
7022 onDocumentEndScriptItems_ = std::make_optional<ScriptItems>(scriptItems);
7023 onDocumentEndScriptItemsByOrder_ = std::nullopt;
7024 EventRecorder::Get().FillWebJsCode(onDocumentEndScriptItems_);
7025 if (delegate_) {
7026 UpdateJavaScriptOnDocumentEnd();
7027 delegate_->JavaScriptOnDocumentEnd();
7028 }
7029 }
7030
UpdateJavaScriptOnDocumentStart()7031 void WebPattern::UpdateJavaScriptOnDocumentStart()
7032 {
7033 if (delegate_ && onDocumentStartScriptItems_.has_value() && !onDocumentStartScriptItemsByOrder_.has_value()) {
7034 delegate_->SetJavaScriptItems(onDocumentStartScriptItems_.value(), ScriptItemType::DOCUMENT_START);
7035 onDocumentStartScriptItems_ = std::nullopt;
7036 }
7037 }
7038
UpdateJavaScriptOnDocumentStartByOrder()7039 void WebPattern::UpdateJavaScriptOnDocumentStartByOrder()
7040 {
7041 if (delegate_ && onDocumentStartScriptItems_.has_value() && onDocumentStartScriptItemsByOrder_.has_value()) {
7042 delegate_->SetJavaScriptItemsByOrder(onDocumentStartScriptItems_.value(), ScriptItemType::DOCUMENT_START,
7043 onDocumentStartScriptItemsByOrder_.value());
7044 onDocumentStartScriptItems_ = std::nullopt;
7045 onDocumentStartScriptItemsByOrder_ = std::nullopt;
7046 }
7047 }
7048
UpdateJavaScriptOnDocumentEndByOrder()7049 void WebPattern::UpdateJavaScriptOnDocumentEndByOrder()
7050 {
7051 if (delegate_ && onDocumentEndScriptItems_.has_value() && onDocumentEndScriptItemsByOrder_.has_value()) {
7052 delegate_->SetJavaScriptItemsByOrder(onDocumentEndScriptItems_.value(), ScriptItemType::DOCUMENT_END,
7053 onDocumentEndScriptItemsByOrder_.value());
7054 onDocumentEndScriptItems_ = std::nullopt;
7055 onDocumentEndScriptItemsByOrder_ = std::nullopt;
7056 }
7057 }
7058
UpdateJavaScriptOnHeadReadyByOrder()7059 void WebPattern::UpdateJavaScriptOnHeadReadyByOrder()
7060 {
7061 if (delegate_ && onHeadReadyScriptItems_.has_value() && onHeadReadyScriptItemsByOrder_.has_value()) {
7062 delegate_->SetJavaScriptItemsByOrder(onHeadReadyScriptItems_.value(), ScriptItemType::DOCUMENT_HEAD_READY,
7063 onHeadReadyScriptItemsByOrder_.value());
7064 onHeadReadyScriptItems_ = std::nullopt;
7065 onHeadReadyScriptItemsByOrder_ = std::nullopt;
7066 }
7067 }
7068
UpdateJavaScriptOnDocumentEnd()7069 void WebPattern::UpdateJavaScriptOnDocumentEnd()
7070 {
7071 if (delegate_ && onDocumentEndScriptItems_.has_value() && !onDocumentEndScriptItemsByOrder_.has_value()) {
7072 delegate_->SetJavaScriptItems(onDocumentEndScriptItems_.value(), ScriptItemType::DOCUMENT_END);
7073 onDocumentEndScriptItems_ = std::nullopt;
7074 }
7075 }
7076
GetAccessibilityNodeById(int64_t accessibilityId)7077 std::shared_ptr<NWeb::NWebAccessibilityNodeInfo> WebPattern::GetAccessibilityNodeById(int64_t accessibilityId)
7078 {
7079 if (!accessibilityState_) {
7080 return nullptr;
7081 }
7082 CHECK_NULL_RETURN(delegate_, nullptr);
7083 return delegate_->GetAccessibilityNodeInfoById(accessibilityId);
7084 }
7085
GetTransitionalNodeById(int64_t accessibilityId)7086 std::shared_ptr<NG::TransitionalNodeInfo> WebPattern::GetTransitionalNodeById(int64_t accessibilityId)
7087 {
7088 if (!accessibilityState_) {
7089 return nullptr;
7090 }
7091 CHECK_NULL_RETURN(delegate_, nullptr);
7092 auto accessNode = delegate_->GetAccessibilityNodeInfoById(accessibilityId);
7093 CHECK_NULL_RETURN(accessNode, nullptr);
7094 return std::make_shared<NG::TransitionalNodeInfo>(accessNode);
7095 }
7096
GetFocusedAccessibilityNode(int64_t accessibilityId,bool isAccessibilityFocus)7097 std::shared_ptr<NG::TransitionalNodeInfo> WebPattern::GetFocusedAccessibilityNode(
7098 int64_t accessibilityId, bool isAccessibilityFocus)
7099 {
7100 if (!accessibilityState_) {
7101 return nullptr;
7102 }
7103 CHECK_NULL_RETURN(delegate_, nullptr);
7104 auto accessNode = delegate_->GetFocusedAccessibilityNodeInfo(accessibilityId, isAccessibilityFocus);
7105 CHECK_NULL_RETURN(accessNode, nullptr);
7106 return std::make_shared<NG::TransitionalNodeInfo>(accessNode);
7107 }
7108
7109
GetAccessibilityNodeByFocusMove(int64_t accessibilityId,int32_t direction)7110 std::shared_ptr<NG::TransitionalNodeInfo> WebPattern::GetAccessibilityNodeByFocusMove(int64_t accessibilityId,
7111 int32_t direction)
7112 {
7113 if (!accessibilityState_) {
7114 return nullptr;
7115 }
7116 CHECK_NULL_RETURN(delegate_, nullptr);
7117 auto accessNode = delegate_->GetAccessibilityNodeInfoByFocusMove(accessibilityId, direction);
7118 CHECK_NULL_RETURN(accessNode, nullptr);
7119 return std::make_shared<NG::TransitionalNodeInfo>(accessNode);
7120 }
7121
ExecuteAction(int64_t accessibilityId,AceAction action,const std::map<std::string,std::string> & actionArguments) const7122 bool WebPattern::ExecuteAction(int64_t accessibilityId, AceAction action,
7123 const std::map<std::string, std::string>& actionArguments) const
7124 {
7125 CHECK_NULL_RETURN(delegate_, false);
7126 if (!accessibilityState_) {
7127 return false;
7128 }
7129 return delegate_->ExecuteAction(accessibilityId, action, actionArguments);
7130 }
7131
SetAccessibilityState(bool state,bool isDelayed)7132 void WebPattern::SetAccessibilityState(bool state, bool isDelayed)
7133 {
7134 CHECK_NULL_VOID(delegate_);
7135 focusedAccessibilityId_ = -1;
7136 if (!state) {
7137 if (!accessibilityState_ || inspectorAccessibilityEnable_ || textBlurAccessibilityEnable_) {
7138 return;
7139 }
7140 accessibilityState_ = state;
7141 delegate_->SetAccessibilityState(state, isDelayed);
7142 return;
7143 }
7144
7145 if (accessibilityState_ != state) {
7146 accessibilityState_ = state;
7147 delegate_->SetAccessibilityState(state, isDelayed);
7148 }
7149 }
7150
UpdateFocusedAccessibilityId(int64_t accessibilityId)7151 void WebPattern::UpdateFocusedAccessibilityId(int64_t accessibilityId)
7152 {
7153 if (!accessibilityState_) {
7154 return;
7155 }
7156 auto host = GetHost();
7157 CHECK_NULL_VOID(host);
7158 auto renderContext = host->GetRenderContext();
7159 CHECK_NULL_VOID(renderContext);
7160
7161 if (accessibilityId > 0) {
7162 focusedAccessibilityId_ = accessibilityId;
7163 } else if (focusedAccessibilityId_ == -1) {
7164 return;
7165 }
7166 RectT<int32_t> rect;
7167 if (focusedAccessibilityId_ <= 0) {
7168 focusedAccessibilityId_ = -1;
7169 renderContext->ResetAccessibilityFocusRect();
7170 renderContext->UpdateAccessibilityFocus(false);
7171 return;
7172 }
7173 if (GetAccessibilityFocusRect(rect, focusedAccessibilityId_)) {
7174 if (rect.Width() <= MIN_ACCESSIBILITY_FOCUS_SIZE || rect.Height() <= MIN_ACCESSIBILITY_FOCUS_SIZE) {
7175 renderContext->ResetAccessibilityFocusRect();
7176 renderContext->UpdateAccessibilityFocus(false);
7177 } else {
7178 renderContext->UpdateAccessibilityFocusRect(rect);
7179 renderContext->UpdateAccessibilityFocus(true);
7180 }
7181 } else {
7182 renderContext->ResetAccessibilityFocusRect();
7183 renderContext->UpdateAccessibilityFocus(false);
7184 }
7185 }
7186
ClearFocusedAccessibilityId()7187 void WebPattern::ClearFocusedAccessibilityId()
7188 {
7189 if (!accessibilityState_) {
7190 return;
7191 }
7192
7193 focusedAccessibilityId_ = -1;
7194 auto host = GetHost();
7195 CHECK_NULL_VOID(host);
7196 auto renderContext = host->GetRenderContext();
7197 CHECK_NULL_VOID(renderContext);
7198 renderContext->ResetAccessibilityFocusRect();
7199 renderContext->UpdateAccessibilityFocus(false);
7200 }
7201
GetSurfaceRSNode() const7202 std::shared_ptr<Rosen::RSNode> WebPattern::GetSurfaceRSNode() const
7203 {
7204 CHECK_NULL_RETURN(renderContextForSurface_, nullptr);
7205 auto rosenRenderContext = AceType::DynamicCast<NG::RosenRenderContext>(renderContextForSurface_);
7206 CHECK_NULL_RETURN(rosenRenderContext, nullptr);
7207 return rosenRenderContext->GetRSNode();
7208 }
7209
GetAccessibilityFocusRect(RectT<int32_t> & paintRect,int64_t accessibilityId) const7210 bool WebPattern::GetAccessibilityFocusRect(RectT<int32_t>& paintRect, int64_t accessibilityId) const
7211 {
7212 if (!accessibilityState_) {
7213 return false;
7214 }
7215 CHECK_NULL_RETURN(delegate_, false);
7216 int32_t rectWidth = 0;
7217 int32_t rectHeight = 0;
7218 int32_t rectX = 0;
7219 int32_t rectY = 0;
7220 bool result = delegate_->GetAccessibilityNodeRectById(accessibilityId, &rectWidth, &rectHeight, &rectX, &rectY);
7221 if (!result) {
7222 return false;
7223 }
7224
7225 paintRect.SetRect(rectX, rectY, rectWidth, rectHeight);
7226 return true;
7227 }
7228
SetTouchEventInfo(const TouchEvent & touchEvent,TouchEventInfo & touchEventInfo,const std::string & embedId)7229 void WebPattern::SetTouchEventInfo(const TouchEvent& touchEvent,
7230 TouchEventInfo& touchEventInfo, const std::string& embedId)
7231 {
7232 CHECK_NULL_VOID(delegate_);
7233 auto host = GetHost();
7234 CHECK_NULL_VOID(host);
7235 auto offset = host->GetTransformRelativeOffset();
7236
7237 TouchEventInfo tempTouchInfo = touchEventInfo_;
7238 if (touchEvent.type == TouchType::DOWN || touchEvent.type == TouchType::UP) {
7239 while (!touchEventQueue_.empty()) {
7240 if (touchEventQueue_.front().GetChangedTouches().front().GetFingerId() == touchEvent.id) {
7241 tempTouchInfo = touchEventQueue_.front();
7242 touchEventQueue_.pop();
7243 break;
7244 } else {
7245 touchEventQueue_.pop();
7246 }
7247 }
7248 }
7249 auto pos = delegate_->GetPosition(embedId);
7250 touchEventInfo.SetSourceDevice(tempTouchInfo.GetSourceDevice());
7251 touchEventInfo.SetTarget(tempTouchInfo.GetTarget());
7252 touchEventInfo.SetForce(tempTouchInfo.GetForce());
7253 touchEventInfo.SetSourceTool(tempTouchInfo.GetSourceTool());
7254 touchEventInfo.SetTargetDisplayId(tempTouchInfo.GetTargetDisplayId());
7255 touchEventInfo.SetDeviceId(tempTouchInfo.GetDeviceId());
7256
7257 TouchLocationInfo changedInfo("onTouch", touchEvent.id);
7258 changedInfo.SetLocalLocation(Offset(touchEvent.x, touchEvent.y));
7259 changedInfo.SetGlobalLocation(Offset(touchEvent.x + offset.GetX() + pos.GetX(),
7260 touchEvent.y + offset.GetY() + pos.GetY()));
7261 changedInfo.SetScreenLocation(Offset(touchEvent.x + offset.GetX() + pos.GetX(),
7262 touchEvent.y + offset.GetY() + pos.GetY()));
7263 changedInfo.SetGlobalDisplayLocation(Offset(touchEvent.x + offset.GetX() + pos.GetX(),
7264 touchEvent.y + offset.GetY() + pos.GetY()));
7265 changedInfo.SetTouchType(touchEvent.type);
7266
7267 SetTouchLocationInfo(touchEvent, changedInfo, tempTouchInfo, touchEventInfo);
7268
7269 touchEventInfo.AddChangedTouchLocationInfo(std::move(changedInfo));
7270 }
7271
SetTouchLocationInfo(const TouchEvent & touchEvent,const TouchLocationInfo & changedInfo,const TouchEventInfo & tempTouchInfo,TouchEventInfo & touchEventInfo)7272 void WebPattern::SetTouchLocationInfo(const TouchEvent& touchEvent, const TouchLocationInfo& changedInfo,
7273 const TouchEventInfo& tempTouchInfo, TouchEventInfo& touchEventInfo)
7274 {
7275 float scaleX = 0.0f;
7276 float scaleY = 0.0f;
7277 const std::list<TouchLocationInfo>& touchList = tempTouchInfo.GetTouches();
7278 for (const TouchLocationInfo& location : touchList) {
7279 if (touchEvent.id == location.GetFingerId()) {
7280 const OHOS::Ace::Offset& localLocation = location.GetLocalLocation();
7281 scaleX = localLocation.GetX() - touchEvent.x;
7282 scaleY = localLocation.GetY() - touchEvent.y;
7283 }
7284 }
7285 for (const TouchLocationInfo& location : touchList) {
7286 TouchLocationInfo info("onTouch", location.GetFingerId());
7287 if (touchEvent.id == location.GetFingerId()) {
7288 info.SetGlobalLocation(changedInfo.GetGlobalLocation());
7289 info.SetLocalLocation(changedInfo.GetLocalLocation());
7290 info.SetScreenLocation(changedInfo.GetScreenLocation());
7291 info.SetGlobalDisplayLocation(changedInfo.GetGlobalDisplayLocation());
7292 info.SetTouchType(changedInfo.GetTouchType());
7293 } else {
7294 const OHOS::Ace::Offset& localLocation = location.GetLocalLocation();
7295 const OHOS::Ace::Offset& globalLocation = location.GetGlobalLocation();
7296 const OHOS::Ace::Offset& screenLocation = location.GetScreenLocation();
7297 const OHOS::Ace::Offset& globalDisplayLocation = location.GetGlobalDisplayLocation();
7298 info.SetGlobalLocation(Offset(globalLocation.GetX() - scaleX, globalLocation.GetY() - scaleY));
7299 info.SetLocalLocation(Offset(localLocation.GetX() - scaleX, localLocation.GetY() - scaleY));
7300 info.SetScreenLocation(Offset(screenLocation.GetX() - scaleX, screenLocation.GetY() - scaleY));
7301 info.SetGlobalDisplayLocation(
7302 Offset(globalDisplayLocation.GetX() - scaleX, globalDisplayLocation.GetY() - scaleY));
7303 info.SetTouchType(location.GetTouchType());
7304 }
7305 touchEventInfo.AddTouchLocationInfo(std::move(info));
7306 }
7307 }
7308
RegisterVisibleAreaChangeCallback(const RefPtr<PipelineContext> & pipeline)7309 void WebPattern::RegisterVisibleAreaChangeCallback(const RefPtr<PipelineContext> &pipeline)
7310 {
7311 auto host = GetHost();
7312 CHECK_NULL_VOID(host);
7313 auto callback = [weak = WeakClaim(this)](bool visible, double ratio) {
7314 auto webPattern = weak.Upgrade();
7315 CHECK_NULL_VOID(webPattern);
7316 if (!visible && !NearZero(ratio)) {
7317 TAG_LOGI(AceLogTag::ACE_WEB, "Fiterate not visible when ratio=%{public}f", ratio);
7318 return;
7319 }
7320 webPattern->OnVisibleAreaChange(visible);
7321 };
7322 std::vector<double> ratioList = {0.0, 1.0};
7323 pipeline->AddVisibleAreaChangeNode(host, ratioList, callback, false, true);
7324 }
7325
GetWordSelection(const std::string & text,int8_t offset)7326 std::vector<int8_t> WebPattern::GetWordSelection(const std::string& text, int8_t offset)
7327 {
7328 // start sync task
7329 std::future<std::vector<int8_t>> future = std::async(std::launch::async, [text, offset]() {
7330 return DataDetectorMgr::GetInstance().GetWordSelection(text, offset);
7331 });
7332 // set timeout
7333 auto status = future.wait_for(std::chrono::milliseconds(AI_TIMEOUT_LIMIT));
7334 if (status == std::future_status::ready) {
7335 return future.get();
7336 } else {
7337 TAG_LOGE(AceLogTag::ACE_WEB, "WebPattern::GetWordSelection timeout! return default");
7338 return std::vector<int8_t> { -1, -1 };
7339 }
7340 }
7341
CheckSafeAreaIsExpand()7342 bool WebPattern::CheckSafeAreaIsExpand()
7343 {
7344 auto host = GetHost();
7345 CHECK_NULL_RETURN(host, false);
7346 auto layoutProperty = host->GetLayoutProperty();
7347 CHECK_NULL_RETURN(layoutProperty, false);
7348 auto &&opts = layoutProperty->GetSafeAreaExpandOpts();
7349 CHECK_NULL_RETURN(opts, false);
7350 if ((opts->type & SAFE_AREA_TYPE_SYSTEM) || (opts->type & SAFE_AREA_TYPE_KEYBOARD)) {
7351 return true;
7352 }
7353 return false;
7354 }
7355
CheckSafeAreaKeyBoard()7356 bool WebPattern::CheckSafeAreaKeyBoard()
7357 {
7358 auto host = GetHost();
7359 CHECK_NULL_RETURN(host, false);
7360 auto layoutProperty = host->GetLayoutProperty();
7361 CHECK_NULL_RETURN(layoutProperty, false);
7362 auto &&opts = layoutProperty->GetSafeAreaExpandOpts();
7363 CHECK_NULL_RETURN(opts, false);
7364 if ((opts->type & SAFE_AREA_TYPE_KEYBOARD) && (opts->edges & SAFE_AREA_EDGE_BOTTOM)) {
7365 TAG_LOGI(AceLogTag::ACE_WEB, "SafeArea type is KEYBOARD.");
7366 return true;
7367 }
7368 return false;
7369 }
7370
Backward()7371 bool WebPattern::Backward()
7372 {
7373 if (!delegate_) {
7374 TAG_LOGE(AceLogTag::ACE_WEB, "delegate is null");
7375 return false;
7376 }
7377 if (delegate_->AccessBackward()) {
7378 delegate_->Backward();
7379 return true;
7380 }
7381 return false;
7382 }
7383
SuggestionSelected(int32_t index)7384 void WebPattern::SuggestionSelected(int32_t index)
7385 {
7386 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::SuggestionSelected index:%{public}d", index);
7387 CHECK_NULL_VOID(delegate_);
7388 delegate_->SuggestionSelected(index);
7389 }
7390
OnShowAutofillPopup(const float offsetX,const float offsetY,const std::vector<std::string> & menu_items)7391 void WebPattern::OnShowAutofillPopup(
7392 const float offsetX, const float offsetY, const std::vector<std::string>& menu_items)
7393 {
7394 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::OnShowAutofillPopup");
7395 isShowAutofillPopup_ = true;
7396 auto host = GetHost();
7397 CHECK_NULL_VOID(host);
7398 auto id = host->GetId();
7399 std::vector<SelectParam> selectParam;
7400 for (auto& item : menu_items) {
7401 selectParam.push_back({ item, "" });
7402 }
7403 auto menu = MenuView::Create(selectParam, id, host->GetTag());
7404 auto context = PipelineContext::GetCurrentContext();
7405 CHECK_NULL_VOID(context);
7406 auto menuContainer = AceType::DynamicCast<FrameNode>(menu->GetChildAtIndex(0));
7407 CHECK_NULL_VOID(menuContainer);
7408 auto menuPattern = menuContainer->GetPattern<MenuPattern>();
7409 CHECK_NULL_VOID(menuPattern);
7410 auto options = menuPattern->GetOptions();
7411 for (auto &&option : options) {
7412 auto selectCallback = [weak = WeakClaim(this)](int32_t index) {
7413 auto webPattern = weak.Upgrade();
7414 CHECK_NULL_VOID(webPattern);
7415 webPattern->SuggestionSelected(index);
7416 };
7417 auto optionNode = AceType::DynamicCast<FrameNode>(option);
7418 if (optionNode) {
7419 auto hub = optionNode->GetOrCreateEventHub<MenuItemEventHub>();
7420 auto optionPattern = optionNode->GetPattern<MenuItemPattern>();
7421 if (!hub || !optionPattern) {
7422 continue;
7423 }
7424 hub->SetOnSelect(std::move(selectCallback));
7425 optionNode->MarkModifyDone();
7426 }
7427 }
7428 auto overlayManager = context->GetOverlayManager();
7429 CHECK_NULL_VOID(overlayManager);
7430 auto offset = GetCoordinatePoint().value_or(OffsetF());
7431 offset.AddX(offsetX);
7432 offset.AddY(offsetY);
7433 menu->GetOrCreateFocusHub()->SetFocusable(false);
7434 overlayManager->DeleteMenu(id);
7435 overlayManager->ShowMenu(id, offset, menu);
7436 }
7437
OnShowAutofillPopupV2(const float offsetX,const float offsetY,const float height,const float width,const std::vector<std::string> & menu_items)7438 void WebPattern::OnShowAutofillPopupV2(
7439 const float offsetX, const float offsetY, const float height, const float width,
7440 const std::vector<std::string>& menu_items)
7441 {
7442 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::OnShowAutofillPopupV2");
7443 isShowAutofillPopup_ = true;
7444 auto host = GetHost();
7445 CHECK_NULL_VOID(host);
7446 std::vector<OptionParam> optionParam;
7447 for (auto& item : menu_items) {
7448 optionParam.push_back({ item, "", nullptr });
7449 }
7450 NG::MenuParam menuParam;
7451 menuParam.isShow = true;
7452 menuParam.setShow = true;
7453 menuParam.placement = Placement::BOTTOM_LEFT;
7454 menuParam.isShowInSubWindow = false;
7455 auto dataListNode = CreateDataListFrameNode(OffsetF(offsetX, offsetY), height, width);
7456 CHECK_NULL_VOID(dataListNode);
7457 auto menu = MenuView::Create(std::move(optionParam), dataListNode->GetId(), dataListNode->GetTag(),
7458 MenuType::MENU, menuParam);
7459 auto menuContainer = AceType::DynamicCast<FrameNode>(menu->GetChildAtIndex(0));
7460 CHECK_NULL_VOID(menuContainer);
7461 auto menuPattern = menuContainer->GetPattern<MenuPattern>();
7462 CHECK_NULL_VOID(menuPattern);
7463 auto options = menuPattern->GetOptions();
7464 for (auto &&option : options) {
7465 auto selectCallback = [weak = WeakClaim(this)](int32_t index) {
7466 auto webPattern = weak.Upgrade();
7467 CHECK_NULL_VOID(webPattern);
7468 webPattern->SuggestionSelected(index);
7469 };
7470 auto optionNode = AceType::DynamicCast<FrameNode>(option);
7471 if (optionNode) {
7472 auto hub = optionNode->GetOrCreateEventHub<MenuItemEventHub>();
7473 auto optionPattern = optionNode->GetPattern<MenuItemPattern>();
7474 if (!hub || !optionPattern) {
7475 continue;
7476 }
7477 hub->SetOnSelect(std::move(selectCallback));
7478 optionNode->MarkModifyDone();
7479 }
7480 }
7481 auto context = dataListNode->GetContext();
7482 CHECK_NULL_VOID(context);
7483 auto overlayManager = context->GetOverlayManager();
7484 CHECK_NULL_VOID(overlayManager);
7485 menu->GetOrCreateFocusHub()->SetFocusable(false);
7486 overlayManager->ShowMenu(dataListNode->GetId(), OffsetF(), menu);
7487 }
7488
OnHideAutofillPopup()7489 void WebPattern::OnHideAutofillPopup()
7490 {
7491 if (!isShowAutofillPopup_) {
7492 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::OnHideAutofillPopup isShowAutofillPopup_ is null");
7493 return;
7494 }
7495 auto host = GetHost();
7496 CHECK_NULL_VOID(host);
7497 auto id = host->GetId();
7498 auto context = PipelineContext::GetCurrentContext();
7499 CHECK_NULL_VOID(context);
7500 auto overlayManager = context->GetOverlayManager();
7501 CHECK_NULL_VOID(overlayManager);
7502 overlayManager->DeleteMenu(id);
7503 RemoveDataListNode();
7504 isShowAutofillPopup_ = false;
7505 }
7506
CreateDataListFrameNode(const OffsetF & offfset,const float height,const float width)7507 RefPtr<FrameNode> WebPattern::CreateDataListFrameNode(const OffsetF& offfset, const float height, const float width)
7508 {
7509 RemoveDataListNode();
7510 auto host = GetHost();
7511 CHECK_NULL_RETURN(host, nullptr);
7512 auto pipeline = host->GetContextRefPtr();
7513 CHECK_NULL_RETURN(host, nullptr);
7514 dataListNodeId_ = ElementRegister::GetInstance()->MakeUniqueId();
7515 auto dataListNode = FrameNode::GetOrCreateFrameNode(
7516 V2::IMAGE_ETS_TAG, dataListNodeId_.value(), []() { return AceType::MakeRefPtr<ImagePattern>(); });
7517 CHECK_NULL_RETURN(dataListNode, nullptr);
7518 auto dataListRenderContext = dataListNode->GetRenderContext();
7519 CHECK_NULL_RETURN(dataListRenderContext, nullptr);
7520 auto dataListGesture = dataListNode->GetOrCreateGestureEventHub();
7521 CHECK_NULL_RETURN(dataListGesture, nullptr);
7522
7523 dataListNode->SetDraggable(false);
7524 dataListGesture->SetDragEvent(nullptr, { PanDirection::DOWN }, 0, Dimension(0));
7525
7526 if (width <= 0 || height <= 0) {
7527 TAG_LOGI(AceLogTag::ACE_WEB, "CreateDataListFrameNode get size(%{public}f, %{public}f) error",
7528 width, height);
7529 return nullptr;
7530 }
7531 dataListRenderContext->UpdatePosition(
7532 OffsetT<Dimension>(Dimension(offfset.GetX()), Dimension(offfset.GetY() - height)));
7533
7534 SizeF dataListSize;
7535 dataListSize.SetWidth(width);
7536 dataListSize.SetHeight(height / pipeline->GetDipScale());
7537 auto dataListProperty = dataListNode->GetLayoutProperty<ImageLayoutProperty>();
7538 dataListProperty->UpdateMarginSelfIdealSize(dataListSize);
7539 MeasureProperty layoutConstraint;
7540 CalcSize idealSize = { CalcLength(Dimension(dataListSize.Width(), DimensionUnit::VP).ConvertToPx()),
7541 CalcLength(Dimension(dataListSize.Height(), DimensionUnit::VP).ConvertToPx()) };
7542 layoutConstraint.selfIdealSize = idealSize;
7543 layoutConstraint.maxSize = idealSize;
7544 dataListNode->UpdateLayoutConstraint(layoutConstraint);
7545 host->AddChild(dataListNode);
7546 dataListNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
7547 dataListNode->MarkModifyDone();
7548 host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
7549 host->MarkModifyDone();
7550 return dataListNode;
7551 }
7552
RemoveDataListNode()7553 void WebPattern::RemoveDataListNode()
7554 {
7555 if (!dataListNodeId_.has_value()) {
7556 return;
7557 }
7558 TAG_LOGI(AceLogTag::ACE_WEB, "RemoveDataListNode");
7559 auto dataListNode = FrameNode::GetFrameNode(V2::IMAGE_ETS_TAG, dataListNodeId_.value());
7560 CHECK_NULL_VOID(dataListNode);
7561 auto context = dataListNode->GetContext();
7562 CHECK_NULL_VOID(context);
7563 auto overlayManager = context->GetOverlayManager();
7564 CHECK_NULL_VOID(overlayManager);
7565 overlayManager->DeleteMenu(dataListNode->GetId());
7566
7567 auto parent = dataListNode->GetParent();
7568 CHECK_NULL_VOID(parent);
7569 parent->RemoveChild(dataListNode);
7570 dataListNodeId_.reset();
7571 parent->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
7572 }
7573
CloseKeyboard()7574 void WebPattern::CloseKeyboard()
7575 {
7576 MenuAvoidKeyboard(true);
7577 InputMethodManager::GetInstance()->CloseKeyboard();
7578 }
7579
GetWebInfoType()7580 WebInfoType WebPattern::GetWebInfoType()
7581 {
7582 std::string factoryLevel;
7583 if (delegate_) {
7584 factoryLevel = delegate_->GetWebInfoType();
7585 }
7586 if (factoryLevel == WEB_INFO_PHONE || factoryLevel == WEB_INFO_DEFAULT) {
7587 return WebInfoType::TYPE_MOBILE;
7588 } else if (factoryLevel == WEB_INFO_TABLET) {
7589 return WebInfoType::TYPE_TABLET;
7590 } else if (factoryLevel == WEB_INFO_PC) {
7591 return WebInfoType::TYPE_2IN1;
7592 }
7593 return WebInfoType::TYPE_UNKNOWN;
7594 }
7595
JsonNodePutDefaultValue(std::unique_ptr<OHOS::Ace::JsonValue> & jsonNode,WebAccessibilityType key,bool value)7596 void WebPattern::JsonNodePutDefaultValue(std::unique_ptr<OHOS::Ace::JsonValue>& jsonNode,
7597 WebAccessibilityType key, bool value)
7598 {
7599 if (!value) {
7600 return;
7601 }
7602 jsonNode->Put(EnumTypeToString(key).c_str(), 1);
7603 }
7604
JsonNodePutDefaultValue(std::unique_ptr<OHOS::Ace::JsonValue> & jsonNode,WebAccessibilityType key,std::string value)7605 void WebPattern::JsonNodePutDefaultValue(std::unique_ptr<OHOS::Ace::JsonValue>& jsonNode,
7606 WebAccessibilityType key, std::string value)
7607 {
7608 if (value.empty()) {
7609 return;
7610 }
7611 jsonNode->Put(EnumTypeToString(key).c_str(), value.c_str());
7612 }
7613
JsonNodePutDefaultValue(std::unique_ptr<OHOS::Ace::JsonValue> & jsonNode,WebAccessibilityType key,int32_t value,int32_t defaultValue)7614 void WebPattern::JsonNodePutDefaultValue(std::unique_ptr<OHOS::Ace::JsonValue>& jsonNode,
7615 WebAccessibilityType key, int32_t value, int32_t defaultValue)
7616 {
7617 if (value == defaultValue) {
7618 return;
7619 }
7620 jsonNode->Put(EnumTypeToString(key).c_str(), value);
7621 }
7622
EnumTypeToString(WebAccessibilityType type)7623 std::string WebPattern::EnumTypeToString(WebAccessibilityType type)
7624 {
7625 return std::to_string(static_cast<int>(type));
7626 }
7627
VectorIntToString(std::vector<int64_t> && vec)7628 std::string WebPattern::VectorIntToString(std::vector<int64_t>&& vec)
7629 {
7630 std::string vecStr;
7631 uint32_t vecLen = vec.size();
7632 if (vecLen < 1) {
7633 return vecStr;
7634 }
7635
7636 for (uint32_t i = 0; i < vecLen - 1; ++i) {
7637 vecStr += std::to_string(vec[i]) + " ";
7638 }
7639 return vecStr + std::to_string(vec[vecLen - 1]);
7640 }
7641
WebNodeInfoToJsonValue(std::shared_ptr<OHOS::Ace::JsonValue> & jsonNodeArray,std::shared_ptr<OHOS::NWeb::NWebAccessibilityNodeInfo> webNodeInfo,std::string & nodeTag,bool isArray)7642 void WebPattern::WebNodeInfoToJsonValue(std::shared_ptr<OHOS::Ace::JsonValue>& jsonNodeArray,
7643 std::shared_ptr<OHOS::NWeb::NWebAccessibilityNodeInfo> webNodeInfo, std::string& nodeTag, bool isArray)
7644 {
7645 auto jsonNode = JsonUtil::Create(true);
7646 jsonNode->Put(WEB_NODE_URL, delegate_ ? delegate_->GetUrl().c_str() : "");
7647 jsonNode->Put(EnumTypeToString(WebAccessibilityType::ID).c_str(), webNodeInfo->GetAccessibilityId());
7648 if (webNodeInfo->GetSelectionEnd() != 0) {
7649 jsonNode->Put(EnumTypeToString(WebAccessibilityType::SEL_START).c_str(), webNodeInfo->GetSelectionStart());
7650 jsonNode->Put(EnumTypeToString(WebAccessibilityType::SEL_END).c_str(), webNodeInfo->GetSelectionEnd());
7651 }
7652 JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::INPUT_TYPE, webNodeInfo->GetInputType(), -1);
7653 JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::LIVE_REGION, webNodeInfo->GetLiveRegion(), -1);
7654 JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::HINT, webNodeInfo->GetHint());
7655 JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::CONTENT, webNodeInfo->GetContent());
7656 JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::ERROR, webNodeInfo->GetError());
7657 JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::CHILD_IDS, VectorIntToString(webNodeInfo->GetChildIds()));
7658 JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::PARENT_ID, webNodeInfo->GetParentId(), -1);
7659 JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::GRID_ROWS, webNodeInfo->GetGridRows(), -1);
7660 JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::GRID_COLS, webNodeInfo->GetGridColumns(), -1);
7661 JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::GRID_SEL_MODE, webNodeInfo->GetGridSelectedMode(), -1);
7662 JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::GRID_ITEM_ROW, webNodeInfo->GetGridItemRow(), -1);
7663 JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::GRID_ITEM_ROW_SPAN, webNodeInfo->GetGridItemRowSpan(), -1);
7664 JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::GRID_ITEM_COL, webNodeInfo->GetGridItemColumn(), -1);
7665 JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::GRID_ITEM_COL_SPAN,
7666 webNodeInfo->GetGridItemColumnSpan(), -1);
7667 JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::PAGE_ID, webNodeInfo->GetPageId(), -1);
7668
7669 if (webNodeInfo->GetRectWidth() != 0 || webNodeInfo->GetRectHeight() != 0) {
7670 jsonNode->Put(EnumTypeToString(WebAccessibilityType::RECTX).c_str(), webNodeInfo->GetRectX());
7671 jsonNode->Put(EnumTypeToString(WebAccessibilityType::RECTY).c_str(), webNodeInfo->GetRectY());
7672 jsonNode->Put(EnumTypeToString(WebAccessibilityType::RECT_WIDTH).c_str(), webNodeInfo->GetRectWidth());
7673 jsonNode->Put(EnumTypeToString(WebAccessibilityType::RECT_HEIGHT).c_str(), webNodeInfo->GetRectHeight());
7674 }
7675
7676 JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::HEADING, webNodeInfo->GetIsHeading());
7677 JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::CHECKED, webNodeInfo->GetIsChecked());
7678 JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::EDITABLE, webNodeInfo->GetIsEditable());
7679 JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::ENABLED, webNodeInfo->GetIsEnabled());
7680 JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::FOCUSED, webNodeInfo->GetIsFocused());
7681 JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::SELECTED, webNodeInfo->GetIsSelected());
7682 JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::CHECKABLE, webNodeInfo->GetIsCheckable());
7683 JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::CLICKABLE, webNodeInfo->GetIsClickable());
7684 JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::FOCUSABLE, webNodeInfo->GetIsFocusable());
7685 JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::SCROLLABLE, webNodeInfo->GetIsScrollable());
7686 JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::PASSWORD, webNodeInfo->GetIsPassword());
7687 JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::VISIBLE, webNodeInfo->GetIsVisible());
7688 JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::PLURAL_LINE, webNodeInfo->GetIsPluralLineSupported());
7689 JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::POPUP, webNodeInfo->GetIsPopupSupported());
7690 JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::DELETABLE, webNodeInfo->GetIsDeletable());
7691 JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::FOCUS, webNodeInfo->GetIsAccessibilityFocus());
7692 JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::NODE_TAG, nodeTag);
7693 isArray ? jsonNodeArray->PutRef(std::move(jsonNode)) : jsonNodeArray->PutRef(nodeTag.c_str(), std::move(jsonNode));
7694 }
7695
GetWebAllInfosImpl(WebNodeInfoCallback cb,int32_t webId,bool needFilter)7696 void WebPattern::GetWebAllInfosImpl(WebNodeInfoCallback cb, int32_t webId, bool needFilter)
7697 {
7698 CHECK_NULL_VOID(delegate_);
7699 std::shared_ptr<OHOS::NWeb::NWebAccessibilityNodeInfo> rootWebNode = delegate_->GetAccessibilityNodeInfoById(-1);
7700 CHECK_NULL_VOID(rootWebNode);
7701
7702 auto jsonNodeArray =
7703 static_cast<std::shared_ptr<JsonValue>>(needFilter ? JsonUtil::Create(true) : JsonUtil::CreateArray(true));
7704 std::queue<uint64_t> que;
7705 for (auto id: rootWebNode->GetChildIds()) {
7706 que.push(id);
7707 }
7708
7709 int nodeCount = 0;
7710 while (!que.empty()) {
7711 uint64_t tmp = que.front();
7712 que.pop();
7713 auto webNodeInfo = delegate_->GetAccessibilityNodeInfoById(tmp);
7714 CHECK_NULL_VOID(webNodeInfo);
7715 auto componentType = webNodeInfo->GetComponentType();
7716 if (needFilter) {
7717 if (componentType.compare(ACCESSIBILITY_GENERIC_CONTAINER) != 0
7718 && componentType.compare(ACCESSIBILITY_PARAGRAPH) != 0
7719 && componentType.compare(ACCESSIBILITY_IMAGE) != 0) {
7720 WebNodeInfoToJsonValue(jsonNodeArray, webNodeInfo, componentType);
7721 }
7722 } else {
7723 WebNodeInfoToJsonValue(jsonNodeArray, webNodeInfo, componentType, true);
7724 }
7725 for (auto id: webNodeInfo->GetChildIds()) {
7726 que.push(id);
7727 }
7728 nodeCount++;
7729 }
7730 TAG_LOGD(AceLogTag::ACE_WEB, "Current web info node count: %{public}d", nodeCount);
7731 cb(jsonNodeArray, webId);
7732 inspectorAccessibilityEnable_ = false;
7733 SetAccessibilityState(false);
7734 }
7735
GetAllWebAccessibilityNodeInfos(WebNodeInfoCallback cb,int32_t webId,bool needFilter)7736 void WebPattern::GetAllWebAccessibilityNodeInfos(WebNodeInfoCallback cb, int32_t webId, bool needFilter)
7737 {
7738 CHECK_NULL_VOID(cb);
7739 inspectorAccessibilityEnable_ = true;
7740 SetAccessibilityState(true);
7741 auto host = GetHost();
7742 CHECK_NULL_VOID(host);
7743 auto pipelineContext = host->GetContext();
7744 CHECK_NULL_VOID(pipelineContext);
7745 auto taskExecutor = pipelineContext->GetTaskExecutor();
7746 taskExecutor->PostDelayedTask([weak = WeakClaim(this), cb, webId, needFilter] () {
7747 auto pattern = weak.Upgrade();
7748 CHECK_NULL_VOID(pattern);
7749 auto startTime = std::chrono::high_resolution_clock::now();
7750 pattern->GetWebAllInfosImpl(cb, webId, needFilter);
7751 auto nowTime = std::chrono::high_resolution_clock::now();
7752 std::chrono::duration<double, std::milli> diff =
7753 std::chrono::duration_cast<std::chrono::milliseconds>(nowTime - startTime);
7754 TAG_LOGD(AceLogTag::ACE_WEB, "GetAllAccessibilityInfo time cost: %{public}f", diff.count());
7755 },
7756 TaskExecutor::TaskType::UI, WEB_ACCESSIBILITY_DELAY_TIME, "GetAllWebAccessibilityNodeInfos");
7757 }
7758
RegisterWebComponentClickCallback(WebComponentClickCallback && callback)7759 void WebPattern::RegisterWebComponentClickCallback(WebComponentClickCallback&& callback)
7760 {
7761 CHECK_NULL_VOID(callback);
7762 webComponentClickCallback_ = std::move(callback);
7763 textBlurAccessibilityEnable_ = true;
7764 SetAccessibilityState(true);
7765 }
7766
UnregisterWebComponentClickCallback()7767 void WebPattern::UnregisterWebComponentClickCallback()
7768 {
7769 webComponentClickCallback_ = nullptr;
7770 textBlurAccessibilityEnable_ = false;
7771 SetAccessibilityState(false);
7772 }
7773
RequestFocus()7774 void WebPattern::RequestFocus()
7775 {
7776 WebRequestFocus();
7777 }
7778
IsCurrentFocus()7779 bool WebPattern::IsCurrentFocus()
7780 {
7781 auto host = GetHost();
7782 CHECK_NULL_RETURN(host, false);
7783 auto eventHub = host->GetOrCreateEventHub<WebEventHub>();
7784 CHECK_NULL_RETURN(eventHub, false);
7785 auto focusHub = eventHub->GetOrCreateFocusHub();
7786 CHECK_NULL_RETURN(focusHub, false);
7787
7788 return focusHub->IsCurrentFocus();
7789 }
7790
OnRebuildFrame()7791 void WebPattern::OnRebuildFrame()
7792 {
7793 auto host = GetHost();
7794 CHECK_NULL_VOID(host);
7795 auto renderContext = host->GetRenderContext();
7796 CHECK_NULL_VOID(renderContext);
7797 CHECK_NULL_VOID(renderContextForSurface_);
7798 renderContext->AddChild(renderContextForSurface_, 0);
7799 CHECK_NULL_VOID(renderContextForPopupSurface_);
7800 if (SystemProperties::GetDeviceType() == DeviceType::TWO_IN_ONE) {
7801 renderContext->AddChild(renderContextForPopupSurface_, 1);
7802 }
7803 }
7804
CreateOverlay(const RefPtr<OHOS::Ace::PixelMap> & pixelMap,int offsetX,int offsetY,int rectWidth,int rectHeight,int pointX,int pointY)7805 void WebPattern::CreateOverlay(const RefPtr<OHOS::Ace::PixelMap>& pixelMap, int offsetX, int offsetY, int rectWidth,
7806 int rectHeight, int pointX, int pointY)
7807 {
7808 if (!imageAnalyzerManager_) {
7809 imageAnalyzerManager_ = std::make_shared<ImageAnalyzerManager>(GetHost(), ImageAnalyzerHolder::WEB);
7810 }
7811 TAG_LOGI(AceLogTag::ACE_WEB,
7812 "CreateOverlay, offsetX=%{public}d, offsetY=%{public}d, width=%{public}d, height=%{public}d", offsetX, offsetY,
7813 rectWidth, rectHeight);
7814 auto callback = [weak = AceType::WeakClaim(this)]() {
7815 auto webPattern = weak.Upgrade();
7816 CHECK_NULL_VOID(webPattern);
7817 webPattern->OnTextSelected();
7818 };
7819 imageAnalyzerManager_->DestroyAnalyzerOverlay();
7820 awaitingOnTextSelected_ = true;
7821 auto selectedTask = [weak = AceType::WeakClaim(this)](bool isSelected) {
7822 auto webPattern = weak.Upgrade();
7823 CHECK_NULL_VOID(webPattern);
7824 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::CreateOverlay selectedTask=%{public}d", isSelected);
7825 webPattern->SetImageOverlaySelectedStatus(isSelected);
7826 if (isSelected) {
7827 webPattern->CloseSelectOverlay();
7828 webPattern->SelectCancel();
7829 webPattern->OnTextSelected();
7830 CHECK_NULL_VOID(webPattern->delegate_);
7831 webPattern->delegate_->OnContextMenuHide("");
7832 }
7833 };
7834 imageAnalyzerManager_->SetNotifySelectedCallback(std::move(selectedTask));
7835 imageAnalyzerManager_->UpdatePressOverlay(
7836 pixelMap, offsetX, offsetY, rectWidth, rectHeight, pointX, pointY, std::move(callback));
7837 imageAnalyzerManager_->CreateAnalyzerOverlay(nullptr);
7838 }
7839
OnOverlayStateChanged(int offsetX,int offsetY,int rectWidth,int rectHeight)7840 void WebPattern::OnOverlayStateChanged(int offsetX, int offsetY, int rectWidth, int rectHeight)
7841 {
7842 if (imageAnalyzerManager_) {
7843 TAG_LOGI(AceLogTag::ACE_WEB,
7844 "OnOverlayStateChanged, offsetX=%{public}d, offsetY=%{public}d, width=%{public}d, height=%{public}d",
7845 offsetX, offsetY, rectWidth, rectHeight);
7846 if (!rectWidth || !rectHeight) {
7847 TAG_LOGE(AceLogTag::ACE_WEB, "OnOverlayStateChanged failed: rect is empty, begin to destroy overlay");
7848 DestroyAnalyzerOverlay();
7849 return;
7850 }
7851 imageAnalyzerManager_->UpdateOverlayStatus(true, offsetX, offsetY, rectWidth, rectHeight);
7852 }
7853 }
7854
OnTextSelected()7855 void WebPattern::OnTextSelected()
7856 {
7857 if (!awaitingOnTextSelected_) {
7858 TAG_LOGD(AceLogTag::ACE_WEB, "OnTextSelected already called, ignored.");
7859 return;
7860 }
7861 awaitingOnTextSelected_ = false;
7862 CHECK_NULL_VOID(delegate_);
7863 delegate_->OnTextSelected();
7864 overlayCreating_ = true;
7865 }
7866
DestroyAnalyzerOverlay()7867 void WebPattern::DestroyAnalyzerOverlay()
7868 {
7869 if (imageAnalyzerManager_ && imageAnalyzerManager_->IsOverlayCreated()) {
7870 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::DestroyAnalyzerOverlay");
7871 imageAnalyzerManager_->DestroyAnalyzerOverlay();
7872 delegate_->OnDestroyImageAnalyzerOverlay();
7873 }
7874 overlayCreating_ = false;
7875 imageOverlayIsSelected_ = false;
7876 awaitingOnTextSelected_ = false;
7877 }
7878
OnAccessibilityHoverEvent(const NG::PointF & point,SourceType source,NG::AccessibilityHoverEventType eventType,TimeStamp time)7879 void WebPattern::OnAccessibilityHoverEvent(
7880 const NG::PointF& point, SourceType source, NG::AccessibilityHoverEventType eventType, TimeStamp time)
7881 {
7882 CHECK_NULL_VOID(delegate_);
7883 delegate_->HandleAccessibilityHoverEvent(point, source, eventType, time);
7884 }
7885
GetSurfaceIdByHtmlElementId(const std::string & htmlElementId)7886 std::string WebPattern::GetSurfaceIdByHtmlElementId(const std::string& htmlElementId)
7887 {
7888 CHECK_NULL_RETURN(delegate_, "");
7889 return delegate_->GetSurfaceIdByHtmlElementId(htmlElementId);
7890 }
7891
GetWebAccessibilityIdBySurfaceId(const std::string & surfaceId)7892 int64_t WebPattern::GetWebAccessibilityIdBySurfaceId(const std::string& surfaceId)
7893 {
7894 CHECK_NULL_RETURN(delegate_, -1);
7895 return delegate_->GetWebAccessibilityIdBySurfaceId(surfaceId);
7896 }
7897
InitMagnifier()7898 void WebPattern::InitMagnifier()
7899 {
7900 TAG_LOGI(AceLogTag::ACE_WEB, "InitMagnifier");
7901 if (!magnifierController_) {
7902 magnifierController_ = MakeRefPtr<MagnifierController>(WeakClaim(this));
7903 }
7904 }
7905
InitializeAccessibility()7906 void WebPattern::InitializeAccessibility()
7907 {
7908 ContainerScope scope(instanceId_);
7909 if (accessibilityChildTreeCallback_.find(instanceId_) != accessibilityChildTreeCallback_.end()) {
7910 return;
7911 }
7912 auto frameNode = frameNode_.Upgrade();
7913 CHECK_NULL_VOID(frameNode);
7914 int64_t accessibilityId = frameNode->GetAccessibilityId();
7915 auto pipeline = PipelineContext::GetCurrentContext();
7916 CHECK_NULL_VOID(pipeline);
7917 auto accessibilityManager = pipeline->GetAccessibilityManager();
7918 CHECK_NULL_VOID(accessibilityManager);
7919 accessibilityChildTreeCallback_[instanceId_] = std::make_shared<WebAccessibilityChildTreeCallback>(
7920 WeakClaim(this), frameNode->GetAccessibilityId());
7921 accessibilityManager->RegisterAccessibilityChildTreeCallback(accessibilityId,
7922 accessibilityChildTreeCallback_[instanceId_]);
7923 if (accessibilityManager->IsRegister()) {
7924 accessibilityChildTreeCallback_[instanceId_]->SetIsDelayed(true);
7925 accessibilityChildTreeCallback_[instanceId_]->OnRegister(pipeline->GetWindowId(),
7926 accessibilityManager->GetTreeId());
7927 }
7928 }
7929
UninitializeAccessibility()7930 void WebPattern::UninitializeAccessibility()
7931 {
7932 ContainerScope scope(instanceId_);
7933 auto frameNode = frameNode_.Upgrade();
7934 CHECK_NULL_VOID(frameNode);
7935 int64_t accessibilityId = frameNode->GetAccessibilityId();
7936 auto pipeline = PipelineContext::GetCurrentContext();
7937 CHECK_NULL_VOID(pipeline);
7938 auto accessibilityManager = pipeline->GetAccessibilityManager();
7939 CHECK_NULL_VOID(accessibilityManager);
7940 if (accessibilityManager->IsRegister()) {
7941 if (accessibilityChildTreeCallback_.find(instanceId_) == accessibilityChildTreeCallback_.end() ||
7942 accessibilityChildTreeCallback_[instanceId_] == nullptr) {
7943 return;
7944 }
7945 accessibilityChildTreeCallback_[instanceId_]->OnDeregister();
7946 }
7947 accessibilityManager->DeregisterAccessibilityChildTreeCallback(accessibilityId);
7948 accessibilityChildTreeCallback_.erase(instanceId_);
7949 }
7950
OnSetAccessibilityChildTree(int32_t childWindowId,int32_t childTreeId)7951 void WebPattern::OnSetAccessibilityChildTree(int32_t childWindowId, int32_t childTreeId)
7952 {
7953 treeId_ = childTreeId;
7954 auto frameNode = frameNode_.Upgrade();
7955 CHECK_NULL_VOID(frameNode);
7956 auto accessibilityProperty = frameNode->GetAccessibilityProperty<AccessibilityProperty>();
7957 if (accessibilityProperty != nullptr) {
7958 accessibilityProperty->SetChildWindowId(childWindowId);
7959 accessibilityProperty->SetChildTreeId(childTreeId);
7960 }
7961 }
7962
OnAccessibilityChildTreeRegister()7963 bool WebPattern::OnAccessibilityChildTreeRegister()
7964 {
7965 ContainerScope scope(instanceId_);
7966 auto pipeline = PipelineContext::GetCurrentContext();
7967 CHECK_NULL_RETURN(pipeline, false);
7968 auto accessibilityManager = pipeline->GetAccessibilityManager();
7969 CHECK_NULL_RETURN(accessibilityManager, false);
7970 if (accessibilitySessionAdapter_ == nullptr) {
7971 accessibilitySessionAdapter_ = AceType::MakeRefPtr<WebAccessibilitySessionAdapter>(WeakClaim(this));
7972 }
7973 auto frameNode = frameNode_.Upgrade();
7974 CHECK_NULL_RETURN(frameNode, false);
7975 int64_t accessibilityId = frameNode->GetAccessibilityId();
7976 return accessibilityManager->RegisterWebInteractionOperationAsChildTree(accessibilityId, WeakClaim(this));
7977 }
7978
OnAccessibilityChildTreeDeregister()7979 bool WebPattern::OnAccessibilityChildTreeDeregister()
7980 {
7981 ContainerScope scope(instanceId_);
7982 auto pipeline = PipelineContext::GetCurrentContext();
7983 CHECK_NULL_RETURN(pipeline, false);
7984 auto accessibilityManager = pipeline->GetAccessibilityManager();
7985 CHECK_NULL_RETURN(accessibilityManager, false);
7986 if (treeId_ == 0) {
7987 TAG_LOGD(AceLogTag::ACE_WEB, "OnAccessibilityChildTreeDeregister: treeId is 0.");
7988 return false;
7989 }
7990 return accessibilityManager->DeregisterWebInteractionOperationAsChildTree(treeId_, WeakClaim(this));
7991 }
7992
GetActiveStatus() const7993 bool WebPattern::GetActiveStatus() const
7994 {
7995 return isActive_;
7996 }
7997
GetBufferSizeByDeviceType()7998 int32_t WebPattern::GetBufferSizeByDeviceType()
7999 {
8000 return (SystemProperties::GetDeviceType() == DeviceType::PHONE ||
8001 SystemProperties::GetDeviceType() == DeviceType::TWO_IN_ONE) ?
8002 ASYNC_SURFACE_QUEUE_SIZE_FOR_PHONE_AND_PC : ASYNC_SURFACE_QUEUE_SIZE_FOR_OTHERS;
8003 }
8004
StartVibraFeedback(const std::string & vibratorType)8005 void WebPattern::StartVibraFeedback(const std::string& vibratorType)
8006 {
8007 if (isEnabledHapticFeedback_) {
8008 NG::VibratorUtils::StartVibraFeedback(vibratorType);
8009 }
8010 }
8011
UpdateTouchpadSlidingStatus(const GestureEvent & event)8012 void WebPattern::UpdateTouchpadSlidingStatus(const GestureEvent& event)
8013 {
8014 isTouchpadSliding_ = false;
8015 if ((event.GetInputEventType() == InputEventType::AXIS) &&
8016 (event.GetSourceTool() == SourceTool::TOUCHPAD)) {
8017 isTouchpadSliding_ = true;
8018 }
8019 }
8020
CloseImageOverlaySelection()8021 bool WebPattern::CloseImageOverlaySelection()
8022 {
8023 if (imageOverlayIsSelected_) {
8024 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::CloseImageOverlaySelection");
8025 DestroyAnalyzerOverlay();
8026 return true;
8027 }
8028 return false;
8029 }
8030
SetDrawSize(double width,double height)8031 void WebPattern::SetDrawSize(double width, double height)
8032 {
8033 drawSize_.SetWidth(width);
8034 drawSize_.SetHeight(height);
8035 }
8036
OnParentScrollDragEndRecursive(RefPtr<NestableScrollContainer> parent)8037 void WebPattern::OnParentScrollDragEndRecursive(RefPtr<NestableScrollContainer> parent)
8038 {
8039 if (isDragEnd_) {
8040 return;
8041 }
8042 if (parent) {
8043 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::OnParentScrollDragEndRecursive");
8044 parent->OnScrollDragEndRecursive();
8045 }
8046 isDragEnd_ = true;
8047 }
8048
GetAccessibilityVisible(int64_t accessibilityId)8049 bool WebPattern::GetAccessibilityVisible(int64_t accessibilityId)
8050 {
8051 if (delegate_) {
8052 return delegate_->GetAccessibilityVisible(accessibilityId);
8053 }
8054 return true;
8055 }
8056
DumpInfo()8057 void WebPattern::DumpInfo()
8058 {
8059 DumpSurfaceInfo();
8060 DumpGpuInfo();
8061 }
8062
DumpGpuInfo()8063 void WebPattern::DumpGpuInfo()
8064 {
8065 float totalSize = 0.0f;
8066 if (delegate_ != nullptr && delegate_->GetNweb() != nullptr) {
8067 totalSize = delegate_->GetNweb()->DumpGpuInfo();
8068 }
8069 if (totalSize > GPU_SERIOUS_ABNORMAL_VALUE) {
8070 totalSize /= SIZE_UNIT * SIZE_UNIT; // 转换成MB
8071 } else if (totalSize > GPU_ABNORMAL_VALUE) {
8072 totalSize /= SIZE_UNIT;
8073 }
8074 totalSize = std::round(totalSize * FLOAT_UNIT) / FLOAT_UNIT; // 变为浮点数
8075 // 使用ostringstream来格式化数字为字符串
8076 std::ostringstream oss;
8077 oss << std::fixed << std::setprecision(DECIMAL_POINTS) << totalSize; // 转换成保留两位小数的字符串
8078 std::string formattedSize = oss.str(); // 获取格式化后的字符串
8079 DumpLog::GetInstance().AddDesc("------------GpuMemoryInfo-----------");
8080 DumpLog::GetInstance().AddDesc("Total Gpu Memory size: " + formattedSize + "(MB)");
8081 }
8082
DumpSurfaceInfo()8083 void WebPattern::DumpSurfaceInfo()
8084 {
8085 if (renderSurface_ != nullptr) {
8086 DumpLog::GetInstance().AddDesc(std::string("surfaceId: ").append(renderSurface_->GetUniqueId()));
8087 }
8088 }
8089
GetWebEventHub()8090 RefPtr<WebEventHub> WebPattern::GetWebEventHub()
8091 {
8092 return GetOrCreateEventHub<WebEventHub>();
8093 }
8094
GetAccessibilitySessionAdapter()8095 RefPtr<AccessibilitySessionAdapter> WebPattern::GetAccessibilitySessionAdapter()
8096 {
8097 return accessibilitySessionAdapter_;
8098 }
8099
OnOptimizeParserBudgetEnabledUpdate(bool value)8100 void WebPattern::OnOptimizeParserBudgetEnabledUpdate(bool value)
8101 {
8102 if (delegate_) {
8103 delegate_->UpdateOptimizeParserBudgetEnabled(value);
8104 }
8105 }
8106
OnWebMediaAVSessionEnabledUpdate(bool enable)8107 void WebPattern::OnWebMediaAVSessionEnabledUpdate(bool enable)
8108 {
8109 if (delegate_) {
8110 delegate_->UpdateWebMediaAVSessionEnabled(enable);
8111 }
8112 }
8113
OnEnableDataDetectorUpdate(bool enable)8114 void WebPattern::OnEnableDataDetectorUpdate(bool enable)
8115 {
8116 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::OnEnableDataDetectorUpdate enable:%{public}d", enable);
8117 auto adapter = GetDataDetectorAdapter();
8118 CHECK_NULL_VOID(adapter);
8119 adapter->SetDataDetectorEnable(enable);
8120 }
8121
PushOverlayInfo(float x,float y,int32_t id)8122 void WebPattern::PushOverlayInfo(float x, float y, int32_t id)
8123 {
8124 TouchInfo touchPoint;
8125 touchPoint.id = id;
8126 touchPoint.x = x;
8127 touchPoint.y = y;
8128 touchOverlayInfo_.push_back(touchPoint);
8129 }
8130
UpdateImageOverlayTouchInfo(int touchPointX,int touchPointY,TouchType touchType)8131 void WebPattern::UpdateImageOverlayTouchInfo(int touchPointX, int touchPointY, TouchType touchType)
8132 {
8133 if (overlayCreating_) {
8134 imageAnalyzerManager_->UpdateOverlayTouchInfo(touchPointX, touchPointY, TouchType::DOWN);
8135 }
8136 }
8137
WebOverlayRequestFocus()8138 void WebPattern::WebOverlayRequestFocus()
8139 {
8140 if (!GetNativeEmbedModeEnabledValue(false)) {
8141 WebRequestFocus();
8142 }
8143 }
8144
GetCurrentLanguage()8145 std::string WebPattern::GetCurrentLanguage()
8146 {
8147 std::string result = "";
8148 if (delegate_) {
8149 result = delegate_->GetCurrentLanguage();
8150 }
8151 return result;
8152 }
8153
OnEnableFollowSystemFontWeightUpdate(bool value)8154 void WebPattern::OnEnableFollowSystemFontWeightUpdate(bool value)
8155 {
8156 if (delegate_) {
8157 delegate_->UpdateEnableFollowSystemFontWeight(value);
8158 }
8159 }
8160
GetTranslateTextCallback(const std::string & result)8161 void WebPattern::GetTranslateTextCallback(const std::string& result)
8162 {
8163 TAG_LOGI(AceLogTag::ACE_WEB, "GetTranslateTextCallback WebId:%{public}d | Text.length:%{public}d",
8164 GetWebId(), static_cast<int32_t>(result.size()));
8165 #if !defined(PREVIEW) && !defined(ACE_UNITTEST) && defined(OHOS_PLATFORM)
8166 auto frameNode = frameNode_.Upgrade();
8167 CHECK_NULL_VOID(frameNode);
8168 auto id = frameNode->GetId();
8169 UiSessionManager::GetInstance()->SendWebTextToAI(id, result);
8170 #endif
8171 }
8172
RegisterTranslateTextJavaScript()8173 void WebPattern::RegisterTranslateTextJavaScript()
8174 {
8175 TAG_LOGI(AceLogTag::ACE_WEB, "RegisterTranslateTextJavaScript WebId:%{public}d", GetWebId());
8176 std::vector<std::string> methods;
8177 methods.push_back(g_translateTextData.registerFunctionName);
8178 auto lambda = [weak = AceType::WeakClaim(this)](const std::vector<std::string>& param) {
8179 auto webPattern = weak.Upgrade();
8180 CHECK_NULL_VOID(webPattern);
8181 if (webPattern && param.size() > 0) {
8182 webPattern->GetTranslateTextCallback(param[0]);
8183 }
8184 };
8185 std::vector<std::function<void(const std::vector<std::string>&)>> funcs;
8186 funcs.push_back(std::move(lambda));
8187 std::string permission = "";
8188 CHECK_NULL_VOID(delegate_);
8189 delegate_->RegisterNativeJavaScriptProxy(g_translateTextData.registerObjectName,
8190 methods, funcs, false, permission, true);
8191 }
8192
RunJsInit()8193 void WebPattern::RunJsInit()
8194 {
8195 if (!g_translateTextData.needTranslate) {
8196 return;
8197 }
8198 if (!isRegisterJsObject_) {
8199 isRegisterJsObject_ = true;
8200 RegisterTranslateTextJavaScript();
8201 return;
8202 }
8203 TAG_LOGI(AceLogTag::ACE_WEB, "run java TranslateScript and InitScript. WebId:%{public}d", GetWebId());
8204 CHECK_NULL_VOID(delegate_);
8205 delegate_->ExecuteTypeScript(g_translateTextData.translateScript, [](std::string result) {});
8206 delegate_->ExecuteTypeScript(g_translateTextData.initScript, [](std::string result) {});
8207 }
8208
GetTranslateText(std::string extraData,std::function<void (std::string)> callback,bool isContinued)8209 void WebPattern::GetTranslateText(std::string extraData, std::function<void(std::string)> callback, bool isContinued)
8210 {
8211 auto host = GetHost();
8212 CHECK_NULL_VOID(host);
8213 auto context = host->GetContext();
8214 CHECK_NULL_VOID(context);
8215 auto taskExecutor = context->GetTaskExecutor();
8216 CHECK_NULL_VOID(taskExecutor);
8217 taskExecutor->PostTask([weak = AceType::WeakClaim(this), jsonData = extraData]() {
8218 std::unique_ptr<JsonValue> json = JsonUtil::ParseJsonString(jsonData);
8219 CHECK_NULL_VOID(json);
8220 g_translateTextData.registerObjectName = json->GetString("registerObjectName");
8221 g_translateTextData.registerFunctionName = json->GetString("registerFunctionName");
8222 g_translateTextData.translateScript = json->GetString("translateScript");
8223 g_translateTextData.initScript = json->GetString("initScript");
8224
8225 auto webPattern = weak.Upgrade();
8226 CHECK_NULL_VOID(webPattern);
8227 TAG_LOGI(AceLogTag::ACE_WEB, "GetTranslateText WebId:%{public}d", webPattern->GetWebId());
8228 TAG_LOGI(AceLogTag::ACE_WEB,
8229 "GetTranslateText 'registerObjectName':%{public}s; 'registerFunctionName':%{public}s",
8230 g_translateTextData.registerObjectName.c_str(), g_translateTextData.registerFunctionName.c_str());
8231 g_translateTextData.needTranslate = true;
8232 webPattern->RunJsInit();
8233 }, TaskExecutor::TaskType::UI, "ArkUIWebGetTranslateText");
8234 }
8235
SendTranslateResult(std::vector<std::string> results,std::vector<int32_t> ids)8236 void WebPattern::SendTranslateResult(std::vector<std::string> results, std::vector<int32_t> ids)
8237 {
8238 return;
8239 }
8240
SendTranslateResult(std::string jscode)8241 void WebPattern::SendTranslateResult(std::string jscode)
8242 {
8243 TAG_LOGI(AceLogTag::ACE_WEB, "SendTranslateResult WebId:%{public}d; Text.length:%{public}d",
8244 GetWebId(), static_cast<int32_t>(jscode.size()));
8245 CHECK_NULL_VOID(delegate_);
8246 delegate_->ExecuteTypeScript(jscode, [](std::string result) {});
8247 }
8248
EndTranslate()8249 void WebPattern::EndTranslate()
8250 {
8251 auto host = GetHost();
8252 CHECK_NULL_VOID(host);
8253 auto context = host->GetContext();
8254 CHECK_NULL_VOID(context);
8255 auto taskExecutor = context->GetTaskExecutor();
8256 CHECK_NULL_VOID(taskExecutor);
8257 taskExecutor->PostTask([weak = AceType::WeakClaim(this)]() {
8258 g_translateTextData.needTranslate = false;
8259 g_translateTextData.translateScript = "";
8260 g_translateTextData.initScript = "";
8261 auto webPattern = weak.Upgrade();
8262 CHECK_NULL_VOID(webPattern);
8263 if (webPattern->isRegisterJsObject_) {
8264 CHECK_NULL_VOID(webPattern->delegate_);
8265 std::string p = g_translateTextData.registerObjectName;
8266 TAG_LOGI(AceLogTag::ACE_WEB, "UnRegister TranslateText JsObject %{public}s", p.c_str());
8267 webPattern->delegate_->UnRegisterNativeArkJSFunction(std::move(p));
8268 webPattern->isRegisterJsObject_ = false;
8269 webPattern->delegate_->Reload();
8270 }
8271 TAG_LOGI(AceLogTag::ACE_WEB, "EndTranslateText WebId:%{public}d", webPattern->GetWebId());
8272 }, TaskExecutor::TaskType::UI, "ArkUIWebEndTranslate");
8273 }
8274
InitRotationEventCallback()8275 void WebPattern::InitRotationEventCallback()
8276 {
8277 if (rotationEndCallbackId_ != 0) {
8278 return;
8279 }
8280
8281 TAG_LOGD(AceLogTag::ACE_WEB, "WebPattern::InitRotationEventCallback");
8282
8283 auto context = PipelineContext::GetCurrentContext();
8284 CHECK_NULL_VOID(context);
8285 rotationEndCallbackId_ = context->RegisterRotationEndCallback(
8286 [weak = WeakClaim(this)]() {
8287 auto pattern = weak.Upgrade();
8288 CHECK_NULL_VOID(pattern);
8289 pattern->RecoverToTopLeft();
8290 }
8291 );
8292 }
8293
UninitRotationEventCallback()8294 void WebPattern::UninitRotationEventCallback()
8295 {
8296 TAG_LOGD(AceLogTag::ACE_WEB, "WebPattern::UninitRotationEventCallback");
8297
8298 auto context = PipelineContext::GetCurrentContext();
8299 CHECK_NULL_VOID(context);
8300 context->UnregisterRotationEndCallback(rotationEndCallbackId_);
8301 rotationEndCallbackId_ = 0;
8302 }
8303
AdjustRotationRenderFit(WindowSizeChangeReason type)8304 void WebPattern::AdjustRotationRenderFit(WindowSizeChangeReason type)
8305 {
8306 if (type != WindowSizeChangeReason::ROTATION) {
8307 return;
8308 }
8309 if (!isAttachedToMainTree_ || !isVisible_) {
8310 TAG_LOGD(AceLogTag::ACE_WEB, "WebPattern::AdjustRotationRenderFit not support");
8311 return;
8312 }
8313
8314 if (delegate_) {
8315 delegate_->MaximizeResize();
8316 }
8317
8318 bool isNwebEx = delegate_->IsNWebEx();
8319 TAG_LOGD(AceLogTag::ACE_WEB, "WebPattern::AdjustRotationRenderFit, isNwebEx: %{public}d", isNwebEx);
8320 if (isNwebEx && SystemProperties::GetDeviceType() == DeviceType::TWO_IN_ONE &&
8321 renderMode_ == RenderMode::ASYNC_RENDER) {
8322 isRotating_ = true;
8323 TAG_LOGD(AceLogTag::ACE_WEB, "WebPattern::AdjustRotationRenderFit, webId: %{public}d", GetWebId());
8324 if (renderContextForSurface_) {
8325 renderContextForSurface_->SetRenderFit(RenderFit::RESIZE_FILL);
8326 }
8327
8328 auto container = Container::Current();
8329 CHECK_NULL_VOID(container);
8330 auto host = GetHost();
8331 CHECK_NULL_VOID(host);
8332 auto pipelineContext = host->GetContext();
8333 CHECK_NULL_VOID(pipelineContext);
8334 auto taskExecutor = pipelineContext->GetTaskExecutor();
8335
8336 std::string taskName = "ArkUIWebRotationDelayTask_" + std::to_string(GetWebId());
8337 taskExecutor->RemoveTask(TaskExecutor::TaskType::UI, taskName);
8338 taskExecutor->PostDelayedTask(
8339 [weak = WeakClaim(this), taskName]() {
8340 auto webPattern = weak.Upgrade();
8341 CHECK_NULL_VOID(webPattern);
8342 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::RestoreRenderFit DelayedTask, task: %{public}s",
8343 taskName.c_str());
8344 webPattern->isRotating_ = false;
8345 if (webPattern->renderContextForSurface_) {
8346 webPattern->renderContextForSurface_->SetRenderFit(RenderFit::TOP_LEFT);
8347 }
8348 }, TaskExecutor::TaskType::UI, MAXIMUM_ROTATION_DELAY_TIME, taskName);
8349 }
8350 }
8351
RecoverToTopLeft()8352 void WebPattern::RecoverToTopLeft()
8353 {
8354 if (!isRotating_) {
8355 return;
8356 }
8357 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::RecoverToTopLeft, webId: %{public}d", GetWebId());
8358 isRotating_ = false;
8359 if (renderContextForSurface_) {
8360 renderContextForSurface_->SetRenderFit(RenderFit::TOP_LEFT);
8361 }
8362 }
8363
GetAccessibilityEventReport()8364 RefPtr<WebAccessibilityEventReport> WebPattern::GetAccessibilityEventReport()
8365 {
8366 if (!webAccessibilityEventReport_) {
8367 webAccessibilityEventReport_ = AceType::MakeRefPtr<WebAccessibilityEventReport>(WeakClaim(this));
8368 }
8369 return webAccessibilityEventReport_;
8370 }
8371
SetTextEventAccessibilityEnable(bool enable)8372 void WebPattern::SetTextEventAccessibilityEnable(bool enable)
8373 {
8374 textBlurAccessibilityEnable_ = enable;
8375 }
8376
GetDataDetectorAdapter()8377 RefPtr<WebDataDetectorAdapter> WebPattern::GetDataDetectorAdapter()
8378 {
8379 if (!webDataDetectorAdapter_) {
8380 webDataDetectorAdapter_ = AceType::MakeRefPtr<WebDataDetectorAdapter>(WeakClaim(this));
8381 }
8382 return webDataDetectorAdapter_;
8383 }
8384
GetDataDetectorEnable()8385 bool WebPattern::GetDataDetectorEnable()
8386 {
8387 if (!webDataDetectorAdapter_) {
8388 return false;
8389 }
8390 return webDataDetectorAdapter_->GetDataDetectorEnable();
8391 }
8392
InitDataDetector()8393 void WebPattern::InitDataDetector()
8394 {
8395 CHECK_NULL_VOID(webDataDetectorAdapter_);
8396 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::InitDataDetector");
8397 webDataDetectorAdapter_->Init();
8398 }
8399
InitAIDetectResult()8400 void WebPattern::InitAIDetectResult()
8401 {
8402 if (!textDetectResult_.menuOptionAndAction.empty()) {
8403 return;
8404 }
8405 auto host = GetHost();
8406 CHECK_NULL_VOID(host);
8407 auto context = host->GetContext();
8408 CHECK_NULL_VOID(context);
8409 auto uiTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
8410 TAG_LOGI(AceLogTag::ACE_WEB, "Web InitAIDetectResult");
8411 uiTaskExecutor.PostTask(
8412 [weak = AceType::WeakClaim(this), instanceId = context->GetInstanceId()] {
8413 ContainerScope scope(instanceId);
8414 auto pattern = weak.Upgrade();
8415 CHECK_NULL_VOID(pattern);
8416 TAG_LOGI(AceLogTag::ACE_WEB, "Get AI entity menu from ai_engine");
8417 DataDetectorMgr::GetInstance().GetAIEntityMenu(pattern->textDetectResult_);
8418 },
8419 "ArkUITextInitDataDetect");
8420 }
8421
CloseDataDetectorMenu()8422 void WebPattern::CloseDataDetectorMenu()
8423 {
8424 CHECK_NULL_VOID(webDataDetectorAdapter_);
8425 webDataDetectorAdapter_->CloseAIMenu();
8426 }
8427
MenuAvoidKeyboard(bool hideOrClose,double height)8428 bool WebPattern::MenuAvoidKeyboard(bool hideOrClose, double height)
8429 {
8430 auto host = GetHost();
8431 CHECK_NULL_RETURN(host, false);
8432 auto pipeline = host->GetContext();
8433 CHECK_NULL_RETURN(pipeline, false);
8434 auto safeAreaManager = pipeline->GetSafeAreaManager();
8435 CHECK_NULL_RETURN(safeAreaManager, false);
8436 auto keyboardInset = safeAreaManager->GetKeyboardWebInset();
8437 if (hideOrClose) {
8438 auto newBottom = std::optional<uint32_t>(keyboardInset.end);
8439 safeAreaManager->UpdateKeyboardWebSafeArea(0, newBottom);
8440 safeAreaManager->SetKeyboardInsetImpl(std::function<SafeAreaInsets::Inset(SafeAreaManager *)>());
8441 } else {
8442 safeAreaManager->UpdateKeyboardWebSafeArea(height);
8443 safeAreaManager->SetKeyboardInsetImpl([](SafeAreaManager* manager) {
8444 CHECK_NULL_RETURN(manager, SafeAreaInsets::Inset());
8445 return manager->GetKeyboardWebInset();
8446 });
8447 }
8448 return true;
8449 }
8450
OnPip(int status,int delegateId,int childId,int frameRoutingId,int width,int height)8451 void WebPattern::OnPip(int status,
8452 int delegateId, int childId, int frameRoutingId, int width, int height)
8453 {
8454 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::OnPip status:%{public}d", status);
8455 Pip(status, delegateId, childId, frameRoutingId, width, height);
8456 }
8457
SetPipNativeWindow(int delegateId,int childId,int frameRoutingId,void * window)8458 void WebPattern::SetPipNativeWindow(int delegateId, int childId, int frameRoutingId, void* window)
8459 {
8460 if (delegate_) {
8461 delegate_->SetPipNativeWindow(delegateId, childId, frameRoutingId, window);
8462 }
8463 }
8464
SendPipEvent(int delegateId,int childId,int frameRoutingId,int event)8465 void WebPattern::SendPipEvent(int delegateId, int childId, int frameRoutingId, int event)
8466 {
8467 if (delegate_) {
8468 delegate_->SendPipEvent(delegateId, childId, frameRoutingId, event);
8469 }
8470 }
8471
CheckVisible()8472 bool WebPattern::CheckVisible()
8473 {
8474 auto host = GetHost();
8475 CHECK_NULL_RETURN(host, false);
8476
8477 if (!host->IsActive() || !host->IsVisible()) {
8478 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::CheckVisible host is inactive or invisible");
8479 return false;
8480 }
8481
8482 auto parent = host->GetAncestorNodeOfFrame(true);
8483 while (parent) {
8484 if (parent->IsWindowBoundary()) {
8485 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::CheckVisible IsWindowBoundary is true");
8486 return true;
8487 }
8488 if (!parent->IsActive() || !parent->IsVisible()) {
8489 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::CheckVisible parent is inactive or invisible");
8490 return false;
8491 }
8492 parent = parent->GetAncestorNodeOfFrame(true);
8493 }
8494 return true;
8495 }
8496
Pip(int status,int delegateId,int childId,int frameRoutingId,int width,int height)8497 bool WebPattern::Pip(int status,
8498 int delegateId, int childId, int frameRoutingId, int width, int height)
8499 {
8500 bool result = false;
8501 uint32_t pipController;
8502 bool init = false;
8503 switch (status) {
8504 case PIP_STATE_ENTER:
8505 case PIP_STATE_HLS_ENTER: {
8506 auto pipeline = PipelineContext::GetCurrentContext();
8507 CHECK_NULL_RETURN(pipeline, false);
8508 napi_env env = CreateEnv();
8509 CHECK_NULL_RETURN(env, false);
8510 PipInfo pipInfo{pipeline->GetWindowId(), delegateId, childId,
8511 frameRoutingId, width, height};
8512 result = CreatePip(status, env, init, pipController, pipInfo);
8513 WEB_CHECK_FALSE_RETURN(result, false);
8514 if (!init) {
8515 result = RegisterPip(pipController);
8516 WEB_CHECK_FALSE_RETURN(result, false);
8517 }
8518 result = StartPip(pipController);
8519 if (result) {
8520 if (!init) {
8521 EnablePip(pipController);
8522 }
8523 }
8524 break;
8525 }
8526 case PIP_STATE_EXIT:
8527 case PIP_STATE_HLS_EXIT: {
8528 result = StopPip(delegateId, childId, frameRoutingId);
8529 break;
8530 }
8531 case PIP_STATE_PLAY: {
8532 result = PlayPip(delegateId, childId, frameRoutingId);
8533 break;
8534 }
8535 case PIP_STATE_PAUSE: {
8536 result = PausePip(delegateId, childId, frameRoutingId);
8537 break;
8538 }
8539 default:
8540 TAG_LOGE(AceLogTag::ACE_WEB, "Pip status:%{public}d", status);
8541 }
8542 return result;
8543 }
8544
CreatePip(int status,napi_env env,bool & init,uint32_t & pipController,const PipInfo & pipInfo)8545 bool WebPattern::CreatePip(int status, napi_env env, bool& init, uint32_t &pipController,
8546 const PipInfo &pipInfo)
8547 {
8548 init = false;
8549 {
8550 std::lock_guard<std::mutex> lock(pipCallbackMapMutex_);
8551 for (auto &it : pipCallbackMap_) {
8552 auto pip = it.second;
8553 if (pip.delegateId == pipInfo.delegateId && pip.childId == pipInfo.childId &&
8554 pip.frameRoutingId == pipInfo.frameRoutingId) {
8555 pipController = it.first;
8556 init = true;
8557 return true;
8558 }
8559 }
8560 }
8561
8562 PictureInPicture_PipTemplateType pipTemplateType = PictureInPicture_PipTemplateType::VIDEO_PLAY;
8563 PictureInPicture_PipControlGroup controlGroup[1] = {
8564 PictureInPicture_PipControlGroup::VIDEO_PLAY_FAST_FORWARD_BACKWARD
8565 };
8566 uint8_t controlGroupLength = 0;
8567 if (status == PIP_STATE_ENTER) {
8568 controlGroupLength = 1;
8569 }
8570 PictureInPicture_PipConfig pipConfig;
8571 OH_PictureInPicture_CreatePipConfig(&pipConfig);
8572 OH_PictureInPicture_SetPipMainWindowId(pipConfig, pipInfo.mainWindowId);
8573 OH_PictureInPicture_SetPipTemplateType(pipConfig, pipTemplateType);
8574 OH_PictureInPicture_SetPipRect(pipConfig, pipInfo.width, pipInfo.height);
8575 OH_PictureInPicture_SetPipControlGroup(pipConfig, controlGroup, controlGroupLength);
8576 OH_PictureInPicture_SetPipNapiEnv(pipConfig, env);
8577 auto errCode = OH_PictureInPicture_CreatePip(pipConfig, &pipController);
8578 if (errCode != 0) {
8579 OH_PictureInPicture_DestroyPipConfig(&pipConfig);
8580 return false;
8581 }
8582 OH_PictureInPicture_DestroyPipConfig(&pipConfig);
8583 struct PipData pipData;
8584 pipData.pipWebPattern = AceType::WeakClaim(this).Upgrade();
8585 pipData.delegateId = pipInfo.delegateId;
8586 pipData.childId = pipInfo.childId;
8587 pipData.frameRoutingId = pipInfo.frameRoutingId;
8588 {
8589 std::lock_guard<std::mutex> lock(pipCallbackMapMutex_);
8590 g_currentControllerId = pipController;
8591 pipCallbackMap_.erase(pipController);
8592 pipCallbackMap_.insert(std::make_pair(pipController, pipData));
8593 pipController_.push_back(pipController);
8594 }
8595 return true;
8596 }
8597
CreateEnv()8598 napi_env WebPattern::CreateEnv()
8599 {
8600 auto engine = EngineHelper::GetCurrentEngine();
8601 if (!engine) {
8602 TAG_LOGE(AceLogTag::ACE_WEB, "Engine is null");
8603 return nullptr;
8604 }
8605
8606 NativeEngine* nativeEngine = engine->GetNativeEngine();
8607 napi_env env = reinterpret_cast<napi_env>(nativeEngine);
8608 if (env == nullptr) {
8609 TAG_LOGE(AceLogTag::ACE_WEB, "NativeEngine is null");
8610 return nullptr;
8611 }
8612 return env;
8613 }
8614
RegisterPip(uint32_t pipController)8615 bool WebPattern::RegisterPip(uint32_t pipController)
8616 {
8617 auto errCode = OH_PictureInPicture_RegisterStartPipCallback(pipController, PipStartPipCallback);
8618 if (errCode != 0) {
8619 TAG_LOGE(AceLogTag::ACE_WEB, "RegisterStartPipCallback err:%{public}d", errCode);
8620 return false;
8621 }
8622 errCode = OH_PictureInPicture_RegisterLifecycleListener(pipController, PipLifecycleCallback);
8623 if (errCode != 0) {
8624 TAG_LOGE(AceLogTag::ACE_WEB, "RegisterLifecycleListener err:%{public}d", errCode);
8625 return false;
8626 }
8627 errCode = OH_PictureInPicture_RegisterControlEventListener(pipController, PipControlEventCallback);
8628 if (errCode != 0) {
8629 TAG_LOGE(AceLogTag::ACE_WEB, "RegisterControlEventListener err:%{public}d", errCode);
8630 return false;
8631 }
8632 errCode = OH_PictureInPicture_RegisterResizeListener(pipController, PipResizeCallback);
8633 if (errCode != 0) {
8634 TAG_LOGE(AceLogTag::ACE_WEB, "RegisterResizeListener err:%{public}d", errCode);
8635 return false;
8636 }
8637 return true;
8638 }
8639
StartPip(uint32_t pipController)8640 bool WebPattern::StartPip(uint32_t pipController)
8641 {
8642 auto errCode = OH_PictureInPicture_StartPip(pipController);
8643 if (errCode != 0) {
8644 TAG_LOGE(AceLogTag::ACE_WEB, "OH_PictureInPicture_StartPip err: %{public}d", errCode);
8645 if (errCode == WINDOW_MANAGER_ERRORCODE_PIP_CREATE_FAILED) {
8646 std::lock_guard<std::mutex> lock(pipCallbackMapMutex_);
8647 for (auto &it : pipCallbackMap_) {
8648 auto pip = it.second;
8649 SendPipEvent(pip.delegateId, pip.childId, pip.frameRoutingId, PIP_STATE_EXIT);
8650 }
8651 }
8652 return false;
8653 }
8654 {
8655 std::lock_guard<std::mutex> lock(pipCallbackMapMutex_);
8656 g_currentControllerId = pipController;
8657 }
8658 return true;
8659 }
8660
EnablePip(uint32_t pipController)8661 void WebPattern::EnablePip(uint32_t pipController)
8662 {
8663 OH_PictureInPicture_UpdatePipControlStatus(
8664 pipController, PictureInPicture_PipControlType::VIDEO_PLAY_PAUSE,
8665 PictureInPicture_PipControlStatus::PLAY);
8666 OH_PictureInPicture_SetPipControlEnabled(
8667 pipController, PictureInPicture_PipControlType::VIDEO_PLAY_PAUSE, true);
8668 OH_PictureInPicture_SetPipControlEnabled(
8669 pipController, PictureInPicture_PipControlType::FAST_FORWARD, true);
8670 OH_PictureInPicture_SetPipControlEnabled(
8671 pipController, PictureInPicture_PipControlType::FAST_BACKWARD, true);
8672 }
8673
StopPip(int delegateId,int childId,int frameRoutingId)8674 bool WebPattern::StopPip(int delegateId, int childId, int frameRoutingId)
8675 {
8676 std::lock_guard<std::mutex> lock(pipCallbackMapMutex_);
8677 for (auto &it : pipCallbackMap_) {
8678 auto pip = it.second;
8679 if (pip.delegateId == delegateId && pip.childId == childId &&
8680 pip.frameRoutingId == frameRoutingId) {
8681 bool result = true;
8682 auto errCode = OH_PictureInPicture_StopPip(it.first);
8683 if (errCode != 0) {
8684 TAG_LOGE(AceLogTag::ACE_WEB, "OH_PictureInPicture_StopPip err: %{public}d", errCode);
8685 result = false;
8686 }
8687 if (g_currentControllerId != it.first) {
8688 g_currentControllerIdStop = true;
8689 auto errCode = OH_PictureInPicture_StopPip(g_currentControllerId);
8690 CHECK_NE_RETURN(errCode, 0, false);
8691 }
8692 return result;
8693 }
8694 }
8695 return false;
8696 }
8697
PlayPip(int delegateId,int childId,int frameRoutingId)8698 bool WebPattern::PlayPip(int delegateId, int childId, int frameRoutingId)
8699 {
8700 bool flag = false;
8701 std::lock_guard<std::mutex> lock(pipCallbackMapMutex_);
8702 for (auto &it : pipCallbackMap_) {
8703 auto pip = it.second;
8704 if (pip.delegateId == delegateId && pip.childId == childId &&
8705 pip.frameRoutingId == frameRoutingId) {
8706 flag = true;
8707 OH_PictureInPicture_UpdatePipControlStatus(it.first,
8708 PictureInPicture_PipControlType::VIDEO_PLAY_PAUSE,
8709 PictureInPicture_PipControlStatus::PLAY);
8710 }
8711 }
8712 if (!flag) {
8713 TAG_LOGE(AceLogTag::ACE_WEB, "PlayPip id no match "
8714 "delegateId:%{public}d, childId:%{public}d frameRoutingId:%{public}d",
8715 delegateId, childId, frameRoutingId);
8716 return false;
8717 }
8718 return true;
8719 }
8720
PausePip(int delegateId,int childId,int frameRoutingId)8721 bool WebPattern::PausePip(int delegateId, int childId, int frameRoutingId)
8722 {
8723 bool flag = false;
8724 std::lock_guard<std::mutex> lock(pipCallbackMapMutex_);
8725 for (auto &it : pipCallbackMap_) {
8726 auto pip = it.second;
8727 if (pip.delegateId == delegateId && pip.childId == childId &&
8728 pip.frameRoutingId == frameRoutingId) {
8729 flag = true;
8730 OH_PictureInPicture_UpdatePipControlStatus(it.first,
8731 PictureInPicture_PipControlType::VIDEO_PLAY_PAUSE,
8732 PictureInPicture_PipControlStatus::PAUSE);
8733 }
8734 }
8735 if (!flag) {
8736 TAG_LOGE(AceLogTag::ACE_WEB, "PausePip id no match "
8737 "delegateId:%{public}d, childId:%{public}d frameRoutingId:%{public}d",
8738 delegateId, childId, frameRoutingId);
8739 return false;
8740 }
8741 return true;
8742 }
8743
OnBypassVsyncConditionUpdate(WebBypassVsyncCondition condition)8744 void WebPattern::OnBypassVsyncConditionUpdate(WebBypassVsyncCondition condition)
8745 {
8746 TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::OnBypassVsyncConditionUpdate condition:%{public}d", condition);
8747 webBypassVsyncCondition_ = condition;
8748 if (delegate_) {
8749 delegate_->UpdateBypassVsyncCondition(condition);
8750 }
8751 }
8752
SetDefaultBackgroundColor()8753 void WebPattern::SetDefaultBackgroundColor()
8754 {
8755 needSetDefaultBackgroundColor_ = true;
8756 }
8757
OnGestureFocusModeUpdate(GestureFocusMode mode)8758 void WebPattern::OnGestureFocusModeUpdate(GestureFocusMode mode)
8759 {
8760 gestureFocusMode_ = mode;
8761 if (delegate_) {
8762 delegate_->UpdateGestureFocusMode(mode);
8763 }
8764 }
8765
UpdateSingleHandleVisible(bool isVisible)8766 void WebPattern::UpdateSingleHandleVisible(bool isVisible)
8767 {
8768 if (delegate_) {
8769 delegate_->UpdateSingleHandleVisible(isVisible);
8770 }
8771 }
8772
OnShowMagnifier()8773 void WebPattern::OnShowMagnifier()
8774 {
8775 ShowMagnifier(static_cast<int>(touchPointX), static_cast<int>(touchPointY));
8776 }
8777
OnHideMagnifier()8778 void WebPattern::OnHideMagnifier()
8779 {
8780 HideMagnifier();
8781 }
8782
8783
SetTouchHandleExistState(bool touchHandleExist)8784 void WebPattern::SetTouchHandleExistState(bool touchHandleExist)
8785 {
8786 if (delegate_) {
8787 delegate_->SetTouchHandleExistState(touchHandleExist);
8788 }
8789 }
8790
IsShowHandle()8791 bool WebPattern::IsShowHandle()
8792 {
8793 return webSelectOverlay_ && webSelectOverlay_->IsShowHandle();
8794 }
8795
InitSurfaceDensityCallback(const RefPtr<PipelineContext> & context)8796 void WebPattern::InitSurfaceDensityCallback(const RefPtr<PipelineContext> &context)
8797 {
8798 TAG_LOGD(AceLogTag::ACE_WEB, "WebPattern::InitSurfaceDensityCallback");
8799 CHECK_NULL_VOID(context);
8800 density_ = context->GetDensity();
8801 if (delegate_) {
8802 delegate_->SetSurfaceDensity(density_);
8803 }
8804 densityCallbackId_ = context->RegisterDensityChangedCallback([weak = WeakClaim(this)](double density) {
8805 auto webPattern = weak.Upgrade();
8806 CHECK_NULL_VOID(webPattern);
8807 webPattern->SetSurfaceDensity(density);
8808 });
8809 }
8810
UnInitSurfaceDensityCallback(const RefPtr<PipelineContext> & context)8811 void WebPattern::UnInitSurfaceDensityCallback(const RefPtr<PipelineContext> &context)
8812 {
8813 TAG_LOGD(AceLogTag::ACE_WEB, "WebPattern::UnInitSurfaceDensityCallback");
8814 CHECK_NULL_VOID(context);
8815 context->UnregisterDensityChangedCallback(densityCallbackId_);
8816 densityCallbackId_ = 0;
8817 }
8818 } // namespace OHOS::Ace::NG
8819