• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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