• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023-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 "input_method_panel.h"
17 
18 #include <tuple>
19 
20 #include "display_info.h"
21 #include "dm_common.h"
22 #include "global.h"
23 #include "input_method_ability.h"
24 #include "input_method_ability_utils.h"
25 #include "inputmethod_trace.h"
26 #include "scene_board_judgement.h"
27 #include "sys_cfg_parser.h"
28 #include "ui/rs_surface_node.h"
29 
30 namespace OHOS {
31 namespace MiscServices {
32 using WMError = OHOS::Rosen::WMError;
33 using WindowGravity = OHOS::Rosen::WindowGravity;
34 using WindowState = OHOS::Rosen::WindowState;
35 using namespace Rosen;
36 constexpr float FIXED_SOFT_KEYBOARD_PANEL_RATIO = 0.7;
37 constexpr float NON_FIXED_SOFT_KEYBOARD_PANEL_RATIO = 1;
38 constexpr int32_t FIXED_PANEL_POS_X = 0;
39 constexpr int32_t ORIGIN_POS_X = 0;
40 constexpr int32_t ORIGIN_POS_Y = 0;
41 constexpr int32_t DEFAULT_AVOID_HEIGHT = -1;
42 std::atomic<uint32_t> InputMethodPanel::sequenceId_ { 0 };
43 constexpr int32_t MAXWAITTIME = 30;
44 constexpr int32_t WAITTIME = 10;
45 InputMethodPanel::~InputMethodPanel() = default;
46 constexpr float GRADIENT_HEIGHT_RATIO = 0.15;
47 
CreatePanel(const std::shared_ptr<AbilityRuntime::Context> & context,const PanelInfo & panelInfo)48 int32_t InputMethodPanel::CreatePanel(
49     const std::shared_ptr<AbilityRuntime::Context> &context, const PanelInfo &panelInfo)
50 {
51     IMSA_HILOGD(
52         "start, type/flag: %{public}d/%{public}d.", static_cast<int32_t>(panelType_), static_cast<int32_t>(panelFlag_));
53     panelType_ = panelInfo.panelType;
54     panelFlag_ = panelInfo.panelFlag;
55     winOption_ = new (std::nothrow) OHOS::Rosen::WindowOption();
56     if (winOption_ == nullptr) {
57         return ErrorCode::ERROR_NULL_POINTER;
58     }
59     if (panelInfo.panelType == PanelType::STATUS_BAR) {
60         winOption_->SetWindowType(OHOS::Rosen::WindowType::WINDOW_TYPE_INPUT_METHOD_STATUS_BAR);
61     } else {
62         winOption_->SetWindowType(OHOS::Rosen::WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT);
63     }
64     WMError wmError = WMError::WM_OK;
65     window_ = OHOS::Rosen::Window::Create(GeneratePanelName(), winOption_, context, wmError);
66     if (wmError == WMError::WM_ERROR_INVALID_PERMISSION || wmError == WMError::WM_ERROR_NOT_SYSTEM_APP) {
67         IMSA_HILOGE("create window failed, permission denied, %{public}d!", wmError);
68         return ErrorCode::ERROR_NOT_IME;
69     }
70     if (window_ == nullptr || wmError != WMError::WM_OK) {
71         IMSA_HILOGE("create window failed: %{public}d!", wmError);
72         return ErrorCode::ERROR_OPERATE_PANEL;
73     }
74     if (SetPanelProperties() != ErrorCode::NO_ERROR) {
75         wmError = window_->Destroy();
76         IMSA_HILOGI("destroy window end, wmError is %{public}d.", wmError);
77         return ErrorCode::ERROR_OPERATE_PANEL;
78     }
79     windowId_ = window_->GetWindowId();
80     IMSA_HILOGI("success, type/flag/windowId: %{public}d/%{public}d/%{public}u.", static_cast<int32_t>(panelType_),
81         static_cast<int32_t>(panelFlag_), windowId_);
82     if (panelInfo.panelType == SOFT_KEYBOARD) {
83         isScbEnable_ = Rosen::SceneBoardJudgement::IsSceneBoardEnabled();
84         if (isScbEnable_) {
85             RegisterKeyboardPanelInfoChangeListener();
86         }
87     }
88     return ErrorCode::NO_ERROR;
89 }
90 
GeneratePanelName()91 std::string InputMethodPanel::GeneratePanelName()
92 {
93     uint32_t sequenceId = GenerateSequenceId();
94     std::string windowName = panelType_ == SOFT_KEYBOARD ? "softKeyboard" + std::to_string(sequenceId) :
95                                                            "statusBar" + std::to_string(sequenceId);
96     IMSA_HILOGD("InputMethodPanel, windowName: %{public}s.", windowName.c_str());
97     return windowName;
98 }
99 
FullScreenPrepare(Rosen::KeyboardLayoutParams & param,const ImmersiveEffect & effect)100 int32_t InputMethodPanel::FullScreenPrepare(Rosen::KeyboardLayoutParams &param, const ImmersiveEffect &effect)
101 {
102     ChangeY changeY = { .portrait = 0, .landscape = 0 };
103     SetChangeY(changeY);
104     if (param.portraitAvoidHeight_ < 0 || param.landscapeAvoidHeight_ < 0 || param.PortraitPanelRect_.posY_  < 0 ||
105         param.LandscapePanelRect_.posY_ < 0) {
106         IMSA_HILOGE("invalid portraitAvoidHeight_:%{public}d, landscapeAvoidHeight_:%{public}d, portraitPosY_:\
107             %{public}d, landscapePosY_:%{public}d", param.portraitAvoidHeight_, param.landscapeAvoidHeight_,
108             param.PortraitPanelRect_.posY_, param.LandscapePanelRect_.posY_);
109         return ErrorCode::ERROR_INVALID_RANGE;
110     }
111 
112     // calculate changeY
113     uint32_t avoidHeightTmp = static_cast<uint32_t>(param.portraitAvoidHeight_) + effect.gradientHeight;
114     if (param.PortraitPanelRect_.height_ < avoidHeightTmp) {
115         changeY.portrait = avoidHeightTmp - param.PortraitPanelRect_.height_;
116         param.PortraitPanelRect_.height_ = avoidHeightTmp;
117         param.PortraitPanelRect_.posY_ = static_cast<int32_t>(SafeSubtract(
118             static_cast<uint32_t>(param.PortraitPanelRect_.posY_), changeY.portrait));
119     }
120     avoidHeightTmp = static_cast<uint32_t>(param.landscapeAvoidHeight_) + effect.gradientHeight;
121     if (param.LandscapePanelRect_.height_ < avoidHeightTmp) {
122         changeY.landscape = avoidHeightTmp - param.LandscapePanelRect_.height_;
123         param.LandscapePanelRect_.height_ = avoidHeightTmp;
124         param.LandscapePanelRect_.posY_ = static_cast<int32_t>(SafeSubtract(
125             static_cast<uint32_t>(param.LandscapePanelRect_.posY_), changeY.landscape));
126     }
127     SetChangeY(changeY);
128 
129     // calculate avoid height
130     auto gradientHeightTemp = static_cast<int32_t>(effect.gradientHeight);
131     if (param.landscapeAvoidHeight_ > INT32_MAX - gradientHeightTemp) {
132         IMSA_HILOGE("landscapeAvoidHeight_ overflow detected");
133         return ErrorCode::ERROR_INVALID_RANGE;
134     }
135     param.landscapeAvoidHeight_ += gradientHeightTemp;
136     if (param.portraitAvoidHeight_ > INT32_MAX - gradientHeightTemp) {
137         IMSA_HILOGE("portraitAvoidHeight_ overflow detected");
138         return ErrorCode::ERROR_INVALID_RANGE;
139     }
140     param.portraitAvoidHeight_ += gradientHeightTemp;
141     return ErrorCode::NO_ERROR;
142 }
143 
NormalImePrepare(Rosen::KeyboardLayoutParams & param,const ImmersiveEffect & effect)144 int32_t InputMethodPanel::NormalImePrepare(Rosen::KeyboardLayoutParams &param, const ImmersiveEffect &effect)
145 {
146     if (param.PortraitPanelRect_.posY_ < 0 || param.LandscapePanelRect_.posY_ < 0) {
147         IMSA_HILOGE("invalid portraitPosY_:%{public}d, landscapePosY_:%{public}d", param.PortraitPanelRect_.posY_,
148             param.LandscapePanelRect_.posY_);
149         return ErrorCode::ERROR_INVALID_RANGE;
150     }
151     uint32_t portraitHeight = param.PortraitPanelRect_.height_ + effect.gradientHeight;
152     uint32_t landscapeHeight = param.LandscapePanelRect_.height_ + effect.gradientHeight;
153 
154     param.PortraitPanelRect_.height_ = portraitHeight;
155     param.LandscapePanelRect_.height_ = landscapeHeight;
156     param.LandscapePanelRect_.posY_ = static_cast<int32_t>(SafeSubtract(
157         static_cast<uint32_t>(param.LandscapePanelRect_.posY_), effect.gradientHeight));
158     param.PortraitPanelRect_.posY_ = static_cast<int32_t>(SafeSubtract(
159         static_cast<uint32_t>(param.PortraitPanelRect_.posY_), effect.gradientHeight));
160 
161     SetChangeY({ .portrait = effect.gradientHeight, .landscape = effect.gradientHeight });
162     return ErrorCode::NO_ERROR;
163 }
164 
PrepareAdjustLayout(Rosen::KeyboardLayoutParams & param,const ImmersiveEffect & effect)165 int32_t InputMethodPanel::PrepareAdjustLayout(Rosen::KeyboardLayoutParams &param, const ImmersiveEffect &effect)
166 {
167     int32_t ret = ErrorCode::NO_ERROR;
168     // full screen keyboard
169     if (param.landscapeAvoidHeight_ != DEFAULT_AVOID_HEIGHT && param.portraitAvoidHeight_ != DEFAULT_AVOID_HEIGHT) {
170         ret = FullScreenPrepare(param, effect);
171     } else {
172         ret = NormalImePrepare(param, effect);
173     }
174     if (ret != ErrorCode::NO_ERROR) {
175         IMSA_HILOGE("prepare failed");
176         return ret;
177     }
178     return ErrorCode::NO_ERROR;
179 }
180 
AdjustLayout(const Rosen::KeyboardLayoutParams & param)181 int32_t InputMethodPanel::AdjustLayout(const Rosen::KeyboardLayoutParams &param)
182 {
183     return AdjustLayout(param, LoadImmersiveEffect());
184 }
185 
AdjustLayout(const Rosen::KeyboardLayoutParams & param,const ImmersiveEffect & effect)186 int32_t InputMethodPanel::AdjustLayout(const Rosen::KeyboardLayoutParams &param, const ImmersiveEffect &effect)
187 {
188     if (window_ == nullptr) {
189         IMSA_HILOGE("window is nullptr!");
190         return ErrorCode::ERROR_NULL_POINTER;
191     }
192 
193     Rosen::KeyboardLayoutParams paramTmp = param;
194     if (effect.gradientHeight != 0) {
195         IMSA_HILOGI("gradientHeight:%{public}u is not zero, need adjust layout", effect.gradientHeight);
196         auto ret = PrepareAdjustLayout(paramTmp, effect);
197         if (ret != ErrorCode::NO_ERROR) {
198             return ret;
199         }
200     } else {
201         SetChangeY({ 0, 0 });
202     }
203     // The actual system panel height includes the gradient height, which may not be consistent with the cached value.
204     auto wmRet = window_->AdjustKeyboardLayout(paramTmp);
205     if (wmRet != WMError::WM_OK) {
206         IMSA_HILOGE("AdjustKeyboardLayout failed, wmError is %{public}d!", wmRet);
207         return ErrorCode::ERROR_WINDOW_MANAGER;
208     }
209     return ErrorCode::NO_ERROR;
210 }
211 
SetPanelProperties()212 int32_t InputMethodPanel::SetPanelProperties()
213 {
214     if (window_ == nullptr) {
215         IMSA_HILOGE("window is nullptr!");
216         return ErrorCode::ERROR_OPERATE_PANEL;
217     }
218     WindowGravity gravity = WindowGravity::WINDOW_GRAVITY_FLOAT;
219     if (panelType_ == SOFT_KEYBOARD && panelFlag_ == FLG_FIXED) {
220         gravity = WindowGravity::WINDOW_GRAVITY_BOTTOM;
221     } else if (panelType_ == SOFT_KEYBOARD && panelFlag_ == FLG_FLOATING) {
222         auto surfaceNode = window_->GetSurfaceNode();
223         if (surfaceNode == nullptr) {
224             IMSA_HILOGE("surfaceNode is nullptr!");
225             return ErrorCode::ERROR_OPERATE_PANEL;
226         }
227         surfaceNode->SetFrameGravity(Rosen::Gravity::TOP_LEFT);
228         Rosen::RSTransactionProxy::GetInstance()->FlushImplicitTransaction();
229     } else if (panelType_ == STATUS_BAR) {
230         auto surfaceNo = window_->GetSurfaceNode();
231         if (surfaceNo == nullptr) {
232             IMSA_HILOGE("surfaceNo is nullptr!");
233             return ErrorCode::ERROR_OPERATE_PANEL;
234         }
235         surfaceNo->SetFrameGravity(Rosen::Gravity::TOP_LEFT);
236         Rosen::RSTransactionProxy::GetInstance()->FlushImplicitTransaction();
237         return ErrorCode::NO_ERROR;
238     }
239     if (!isScbEnable_) {
240         WMError wmError = window_->SetWindowGravity(gravity, invalidGravityPercent);
241         if (wmError != WMError::WM_OK) {
242             IMSA_HILOGE("failed to set window gravity, wmError is %{public}d, start destroy window!", wmError);
243             return ErrorCode::ERROR_OPERATE_PANEL;
244         }
245         return ErrorCode::NO_ERROR;
246     }
247     auto params = GetKeyboardLayoutParams();
248     params.gravity_ = gravity;
249     auto ret = AdjustLayout(params);
250     if (ret != ErrorCode::NO_ERROR) {
251         IMSA_HILOGE("SetWindowGravity failed, ret is %{public}d, start destroy window!", ret);
252         return ErrorCode::ERROR_OPERATE_PANEL;
253     }
254     SetKeyboardLayoutParams(params);
255     return ErrorCode::NO_ERROR;
256 }
257 
DestroyPanel()258 int32_t InputMethodPanel::DestroyPanel()
259 {
260     auto ret = HidePanel();
261     if (ret != ErrorCode::NO_ERROR) {
262         IMSA_HILOGE("InputMethodPanel, hide panel failed, ret: %{public}d!", ret);
263     }
264     if (window_ == nullptr) {
265         IMSA_HILOGE("window_ is nullptr!");
266         return ErrorCode::ERROR_NULL_POINTER;
267     }
268     if (panelType_ == SOFT_KEYBOARD) {
269         UnregisterKeyboardPanelInfoChangeListener();
270     }
271     auto result = window_->Destroy();
272     IMSA_HILOGI("destroy ret: %{public}d", result);
273     return ErrorCode::NO_ERROR;
274 }
275 
GetResizeParams(Rosen::Rect & portrait,Rosen::Rect & landscape,uint32_t width,uint32_t height)276 int32_t InputMethodPanel::GetResizeParams(
277     Rosen::Rect &portrait, Rosen::Rect &landscape, uint32_t width, uint32_t height)
278 {
279     LayoutParams currParams;
280     DisplaySize displaySize;
281     auto ret = GetDisplaySize(displaySize);
282     if (ret != ErrorCode::NO_ERROR) {
283         IMSA_HILOGE("failed to GetDisplaySize ret: %{public}d", ret);
284         return ret;
285     }
286 
287     if (displaySize.portrait.height == displaySize.portrait.width) {
288         portrait.height_ = height;
289         portrait.width_ = width;
290         landscape.height_ = height;
291         landscape.width_ = width;
292         IMSA_HILOGI("isScreenEqual now, update screen equal size");
293         return ErrorCode::NO_ERROR;
294     }
295 
296     if (IsDisplayUnfolded()) {
297         std::lock_guard<std::mutex> lock(unfoldResizeParamMutex_);
298         IMSA_HILOGI("foldable device without fold state");
299         if (!isInEnhancedAdjust_.load()) {
300             RectifyResizeParams(resizePanelUnfoldParams_, displaySize);
301         }
302         currParams = resizePanelUnfoldParams_;
303     } else {
304         std::lock_guard<std::mutex> lock(foldResizeParamMutex_);
305         IMSA_HILOGI("foldable device with fold state or non-foldable device");
306         if (!isInEnhancedAdjust_.load()) {
307             RectifyResizeParams(resizePanelFoldParams_, displaySize);
308         }
309         currParams = resizePanelFoldParams_;
310     }
311 
312     UpdateRectParams(portrait, landscape, width, height, currParams);
313     return ErrorCode::NO_ERROR;
314 }
315 
RectifyResizeParams(LayoutParams & params,const DisplaySize & displaySize)316 void InputMethodPanel::RectifyResizeParams(LayoutParams &params, const DisplaySize &displaySize)
317 {
318     params.portraitRect.height_ =
319         std::min(static_cast<float>(displaySize.portrait.height) * FIXED_SOFT_KEYBOARD_PANEL_RATIO,
320             static_cast<float>(params.portraitRect.height_));
321     params.landscapeRect.height_ =
322         std::min(static_cast<float>(displaySize.landscape.height) * FIXED_SOFT_KEYBOARD_PANEL_RATIO,
323             static_cast<float>(params.landscapeRect.height_));
324     params.portraitRect.width_ =
325         std::min(displaySize.portrait.width, params.portraitRect.width_);
326     params.landscapeRect.width_ =
327         std::min(displaySize.landscape.width, params.landscapeRect.width_);
328 }
329 
UpdateRectParams(Rosen::Rect & portrait,Rosen::Rect & landscape,uint32_t width,uint32_t height,const LayoutParams & currParams)330 void InputMethodPanel::UpdateRectParams(
331     Rosen::Rect &portrait, Rosen::Rect &landscape, uint32_t width, uint32_t height, const LayoutParams &currParams)
332 {
333     if (IsDisplayPortrait()) {
334         landscape.height_ = currParams.landscapeRect.height_;
335         landscape.width_ = currParams.landscapeRect.width_;
336         portrait.height_ = height;
337         portrait.width_ = width;
338         IMSA_HILOGI("isPortrait now, update portrait size");
339     } else {
340         portrait.height_ = currParams.portraitRect.height_;
341         portrait.width_ = currParams.portraitRect.width_;
342         landscape.height_ = height;
343         landscape.width_ = width;
344         IMSA_HILOGI("isLandscapeRect now, update landscape size");
345     }
346 }
347 
UpdateResizeParams()348 void InputMethodPanel::UpdateResizeParams()
349 {
350     auto layoutParams = GetKeyboardLayoutParams();
351     if (IsDisplayUnfolded()) {
352         std::lock_guard<std::mutex> lock(unfoldResizeParamMutex_);
353         IMSA_HILOGI("foldable device without fold state");
354         resizePanelUnfoldParams_ = { layoutParams.LandscapeKeyboardRect_, layoutParams.PortraitKeyboardRect_ };
355     } else {
356         std::lock_guard<std::mutex> lock(foldResizeParamMutex_);
357         IMSA_HILOGI("foldable device in fold state or non-foldable device");
358         resizePanelFoldParams_ = { layoutParams.LandscapeKeyboardRect_, layoutParams.PortraitKeyboardRect_ };
359     }
360 }
361 
ResizeEnhancedPanel(uint32_t width,uint32_t height)362 int32_t InputMethodPanel::ResizeEnhancedPanel(uint32_t width, uint32_t height)
363 {
364     auto layoutParam = GetEnhancedLayoutParams();
365     auto ret = GetResizeParams(layoutParam.portrait.rect, layoutParam.landscape.rect, width, height);
366     if (ret != ErrorCode::NO_ERROR) {
367         IMSA_HILOGE("failed to GetResizeParams, ret: %{public}d", ret);
368         return ret;
369     }
370     auto hotAreas = GetHotAreas();
371     ret = AdjustPanelRect(panelFlag_, layoutParam, hotAreas);
372     if (ret != ErrorCode::NO_ERROR) {
373         IMSA_HILOGE("failed to AdjustPanelRect, ret: %{public}d", ret);
374         return ErrorCode::ERROR_OPERATE_PANEL;
375     }
376     std::lock_guard<std::mutex> lock(keyboardSizeLock_);
377     keyboardSize_ = { width, height };
378     IMSA_HILOGI("success, width/height: %{public}u/%{public}u.", width, height);
379     return ErrorCode::NO_ERROR;
380 }
381 
ResizeWithoutAdjust(uint32_t width,uint32_t height)382 int32_t InputMethodPanel::ResizeWithoutAdjust(uint32_t width, uint32_t height)
383 {
384     if (!IsSizeValid(width, height)) {
385         IMSA_HILOGE("size is invalid!");
386         return ErrorCode::ERROR_BAD_PARAMETERS;
387     }
388     auto ret = window_->Resize(width, height);
389     if (ret != WMError::WM_OK) {
390         IMSA_HILOGE("failed to resize, ret: %{public}d", ret);
391         return ErrorCode::ERROR_OPERATE_PANEL;
392     }
393     std::lock_guard<std::mutex> lock(keyboardSizeLock_);
394     keyboardSize_ = { width, height };
395     IMSA_HILOGI("success, width/height: %{public}u/%{public}u.", width, height);
396     return ErrorCode::NO_ERROR;
397 }
398 
ResizePanel(uint32_t width,uint32_t height)399 int32_t InputMethodPanel::ResizePanel(uint32_t width, uint32_t height)
400 {
401     if (!IsSizeValid(width, height)) {
402         IMSA_HILOGE("size is invalid!");
403         return ErrorCode::ERROR_BAD_PARAMETERS;
404     }
405     auto currentParams = GetEnhancedLayoutParams();
406     LayoutParams targetParams = { .landscapeRect = currentParams.landscape.rect,
407         .portraitRect = currentParams.portrait.rect };
408     auto ret = GetResizeParams(targetParams.portraitRect, targetParams.landscapeRect, width, height);
409     if (ret != ErrorCode::NO_ERROR) {
410         IMSA_HILOGE("failed to GetResizeParams, ret: %{public}d", ret);
411         return ret;
412     }
413     ret = AdjustPanelRect(panelFlag_, targetParams);
414     if (ret != ErrorCode::NO_ERROR) {
415         IMSA_HILOGE("failed to resize, ret: %{public}d", ret);
416         return ErrorCode::ERROR_OPERATE_PANEL;
417     }
418     std::lock_guard<std::mutex> lock(keyboardSizeLock_);
419     keyboardSize_ = { width, height };
420     IMSA_HILOGI("success, width/height: %{public}u/%{public}u.", width, height);
421     return ErrorCode::NO_ERROR;
422 }
423 
Resize(uint32_t width,uint32_t height)424 int32_t InputMethodPanel::Resize(uint32_t width, uint32_t height)
425 {
426     if (window_ == nullptr) {
427         IMSA_HILOGE("window is nullptr!");
428         return ErrorCode::ERROR_NULL_POINTER;
429     }
430     if (!isScbEnable_ || window_->GetType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
431         return ResizeWithoutAdjust(width, height);
432     }
433     if (isInEnhancedAdjust_.load()) {
434         return ResizeEnhancedPanel(width, height);
435     }
436     return ResizePanel(width, height);
437 }
438 
MovePanelRect(int32_t x,int32_t y)439 int32_t InputMethodPanel::MovePanelRect(int32_t x, int32_t y)
440 {
441     auto currentParams = GetEnhancedLayoutParams();
442     LayoutParams params = { currentParams.landscape.rect, currentParams.portrait.rect };
443     if (IsDisplayPortrait()) {
444         params.portraitRect.posX_ = x;
445         params.portraitRect.posY_ = y;
446         IMSA_HILOGI("isPortrait now, updata portrait size");
447     } else {
448         params.landscapeRect.posX_ = x;
449         params.landscapeRect.posY_ = y;
450         IMSA_HILOGI("isLandscapeRect now, updata landscape size");
451     }
452     auto ret = AdjustPanelRect(panelFlag_, params, false);
453     IMSA_HILOGI("x/y: %{public}d/%{public}d, ret = %{public}d", x, y, ret);
454     return ret == ErrorCode::NO_ERROR ? ErrorCode::NO_ERROR : ErrorCode::ERROR_PARAMETER_CHECK_FAILED;
455 }
456 
MoveEnhancedPanelRect(int32_t x,int32_t y)457 int32_t InputMethodPanel::MoveEnhancedPanelRect(int32_t x, int32_t y)
458 {
459     auto params = GetEnhancedLayoutParams();
460     if (IsDisplayPortrait()) {
461         params.portrait.rect.posX_ = x;
462         params.portrait.rect.posY_ = y;
463     } else {
464         params.landscape.rect.posX_ = x;
465         params.landscape.rect.posY_ = y;
466     }
467     auto hotAreas = GetHotAreas();
468     auto ret = AdjustPanelRect(panelFlag_, params, hotAreas);
469     IMSA_HILOGI("x/y: %{public}d/%{public}d, ret = %{public}d", x, y, ret);
470     return ret == ErrorCode::NO_ERROR ? ErrorCode::NO_ERROR : ErrorCode::ERROR_PARAMETER_CHECK_FAILED;
471 }
472 
MoveTo(int32_t x,int32_t y)473 int32_t InputMethodPanel::MoveTo(int32_t x, int32_t y)
474 {
475     if (window_ == nullptr) {
476         IMSA_HILOGE("window_ is nullptr!");
477         return ErrorCode::ERROR_NULL_POINTER;
478     }
479     if (panelType_ == SOFT_KEYBOARD && panelFlag_ == FLG_FIXED) {
480         IMSA_HILOGE("FLG_FIXED panel can not moveTo!");
481         return ErrorCode::NO_ERROR;
482     }
483     if (!isScbEnable_ || window_->GetType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
484         auto ret = window_->MoveTo(x, y);
485         IMSA_HILOGI("x/y: %{public}d/%{public}d, ret = %{public}d", x, y, ret);
486         return ret == WMError::WM_ERROR_INVALID_PARAM ? ErrorCode::ERROR_PARAMETER_CHECK_FAILED : ErrorCode::NO_ERROR;
487     } else if (isInEnhancedAdjust_.load()) {
488         return MoveEnhancedPanelRect(x, y);
489     } else {
490         return MovePanelRect(x, y);
491     }
492 }
493 
StartMoving()494 int32_t InputMethodPanel::StartMoving()
495 {
496     if (window_ == nullptr) {
497         IMSA_HILOGE("window_ is nullptr!");
498         return ErrorCode::ERROR_IME;
499     }
500     if (panelType_ == PanelType::SOFT_KEYBOARD &&
501         !(panelFlag_ == FLG_FLOATING || panelFlag_ == FLG_CANDIDATE_COLUMN)) {
502         IMSA_HILOGE("invalid panel flag: %{public}d", panelFlag_);
503         return ErrorCode::ERROR_INVALID_PANEL_FLAG;
504     }
505     auto ret = window_->StartMoveWindow();
506     if (ret == WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT) {
507         IMSA_HILOGE("window manager service not support error ret = %{public}d.", ret);
508         return ErrorCode::ERROR_DEVICE_UNSUPPORTED;
509     }
510     if (ret != WmErrorCode::WM_OK) {
511         IMSA_HILOGE("window manager service error ret = %{public}d.", ret);
512         return ErrorCode::ERROR_WINDOW_MANAGER;
513     }
514     IMSA_HILOGI("StartMoving  success!");
515     return ErrorCode::NO_ERROR;
516 }
517 
GetDisplayId(uint64_t & displayId)518 int32_t InputMethodPanel::GetDisplayId(uint64_t &displayId)
519 {
520     if (window_ == nullptr) {
521         IMSA_HILOGE("window_ is nullptr!");
522         return ErrorCode::ERROR_IME;
523     }
524     displayId = window_->GetDisplayId();
525     if (displayId == Rosen::DISPLAY_ID_INVALID) {
526         IMSA_HILOGE("display id invalid!");
527         return ErrorCode::ERROR_WINDOW_MANAGER;
528     }
529     IMSA_HILOGD("GetDisplayId success dispalyId = %{public}" PRIu64 "", displayId);
530     return ErrorCode::NO_ERROR;
531 }
532 
AdjustKeyboard()533 int32_t InputMethodPanel::AdjustKeyboard()
534 {
535     isAdjustInfoInitialized_.store(false);
536     int32_t ret = 0;
537     auto params = GetEnhancedLayoutParams();
538     if (isInEnhancedAdjust_.load()) {
539         DisplaySize displaySize;
540         ret = GetDisplaySize(displaySize);
541         if (ret != ErrorCode::NO_ERROR) {
542             IMSA_HILOGE("failed to GetDisplaySize ret: %{public}d", ret);
543             return ret;
544         }
545         params.portrait.avoidY = static_cast<int32_t>(displaySize.portrait.height - params.portrait.avoidHeight);
546         params.landscape.avoidY = static_cast<int32_t>(displaySize.landscape.height - params.landscape.avoidHeight);
547         auto hotAreas = GetHotAreas();
548         ret = AdjustPanelRect(panelFlag_, params, hotAreas);
549     } else {
550         LayoutParams layoutParams = { params.landscape.rect, params.portrait.rect };
551         ret = AdjustPanelRect(panelFlag_, layoutParams);
552     }
553     if (ret != ErrorCode::NO_ERROR) {
554         IMSA_HILOGE("failed to adjust keyboard, ret: %{public}d", ret);
555         return ErrorCode::ERROR_OPERATE_PANEL;
556     }
557     IMSA_HILOGI("adjust keyboard success");
558     return ErrorCode::NO_ERROR;
559 }
560 
AdjustPanelRect(const PanelFlag panelFlag,const LayoutParams & layoutParams,bool needUpdateRegion)561 int32_t InputMethodPanel::AdjustPanelRect(
562     const PanelFlag panelFlag, const LayoutParams &layoutParams, bool needUpdateRegion)
563 {
564     if (window_ == nullptr) {
565         IMSA_HILOGE("window_ is nullptr!");
566         return ErrorCode::ERROR_WINDOW_MANAGER;
567     }
568     KeyboardLayoutParams resultParams;
569     int32_t result = ParseParams(panelFlag, layoutParams, resultParams);
570     if (result != ErrorCode::NO_ERROR) {
571         IMSA_HILOGE("failed to parse panel rect, result: %{public}d!", result);
572         return result;
573     }
574     auto ret = AdjustLayout(resultParams);
575     if (ret != ErrorCode::NO_ERROR) {
576         IMSA_HILOGE("AdjustPanelRect error, err: %{public}d!", ret);
577         return ErrorCode::ERROR_WINDOW_MANAGER;
578     }
579     UpdateLayoutInfo(panelFlag, layoutParams, {}, resultParams, false);
580     UpdateResizeParams();
581     if (needUpdateRegion) {
582         UpdateHotAreas();
583     }
584     IMSA_HILOGI("success, type/flag: %{public}d/%{public}d.", static_cast<int32_t>(panelType_),
585         static_cast<int32_t>(panelFlag_));
586     return ErrorCode::NO_ERROR;
587 }
588 
ConvertToWMSParam(PanelFlag panelFlag,const EnhancedLayoutParams & layoutParams)589 Rosen::KeyboardLayoutParams InputMethodPanel::ConvertToWMSParam(
590     PanelFlag panelFlag, const EnhancedLayoutParams &layoutParams)
591 {
592     Rosen::KeyboardLayoutParams wmsParams;
593     if (panelFlag == PanelFlag::FLG_FIXED) {
594         wmsParams.gravity_ = WindowGravity::WINDOW_GRAVITY_BOTTOM;
595     } else {
596         wmsParams.gravity_ = WindowGravity::WINDOW_GRAVITY_FLOAT;
597     }
598     wmsParams.LandscapeKeyboardRect_ = layoutParams.landscape.rect;
599     wmsParams.LandscapePanelRect_ = layoutParams.landscape.panelRect;
600     wmsParams.PortraitKeyboardRect_ = layoutParams.portrait.rect;
601     wmsParams.PortraitPanelRect_ = layoutParams.portrait.panelRect;
602     wmsParams.portraitAvoidHeight_ = layoutParams.portrait.avoidHeight;
603     wmsParams.landscapeAvoidHeight_ = layoutParams.landscape.avoidHeight;
604     return wmsParams;
605 }
606 
ConvertToWMSHotArea(const HotAreas & hotAreas)607 Rosen::KeyboardTouchHotAreas InputMethodPanel::ConvertToWMSHotArea(const HotAreas &hotAreas)
608 {
609     return { .landscapeKeyboardHotAreas_ = hotAreas.landscape.keyboardHotArea,
610         .portraitKeyboardHotAreas_ = hotAreas.portrait.keyboardHotArea,
611         .landscapePanelHotAreas_ = hotAreas.landscape.panelHotArea,
612         .portraitPanelHotAreas_ = hotAreas.portrait.panelHotArea };
613 }
614 
IsEnhancedParamValid(PanelFlag panelFlag,EnhancedLayoutParams & params)615 int32_t InputMethodPanel::IsEnhancedParamValid(PanelFlag panelFlag, EnhancedLayoutParams &params)
616 {
617     if (window_ == nullptr) {
618         IMSA_HILOGE("window_ is nullptr!");
619         return ErrorCode::ERROR_WINDOW_MANAGER;
620     }
621     if (panelType_ != PanelType::SOFT_KEYBOARD) {
622         IMSA_HILOGE("not soft keyboard panel");
623         return ErrorCode::ERROR_INVALID_PANEL_TYPE;
624     }
625     FullPanelAdjustInfo adjustInfo;
626     auto ret = GetAdjustInfo(panelFlag, adjustInfo);
627     if (ret != ErrorCode::NO_ERROR) {
628         return ret;
629     }
630     ret = ParseEnhancedParams(panelFlag, adjustInfo, params);
631     if (ret != ErrorCode::NO_ERROR) {
632         return ret;
633     }
634     return ErrorCode::NO_ERROR;
635 }
636 
AdjustPanelRect(PanelFlag panelFlag,EnhancedLayoutParams params,HotAreas hotAreas)637 int32_t InputMethodPanel::AdjustPanelRect(PanelFlag panelFlag, EnhancedLayoutParams params, HotAreas hotAreas)
638 {
639     if (window_ == nullptr) {
640         IMSA_HILOGE("window_ is nullptr!");
641         return ErrorCode::ERROR_WINDOW_MANAGER;
642     }
643     if (panelType_ != PanelType::SOFT_KEYBOARD) {
644         IMSA_HILOGE("not soft keyboard panel");
645         return ErrorCode::ERROR_INVALID_PANEL_TYPE;
646     }
647     FullPanelAdjustInfo adjustInfo;
648     if (IsNeedConfig()) {
649         auto ret = GetAdjustInfo(panelFlag, adjustInfo);
650         if (ret != ErrorCode::NO_ERROR) {
651             return ret;
652         }
653     }
654     auto ret = ParseEnhancedParams(panelFlag, adjustInfo, params);
655     if (ret != ErrorCode::NO_ERROR) {
656         return ret;
657     }
658     // adjust rect
659     auto lastWmsParam = GetKeyboardLayoutParams();
660     auto lastIsEnhanced = isInEnhancedAdjust_.load();
661     auto lastParams = GetEnhancedLayoutParams();
662     auto lastPanelFlag = panelFlag_;
663     auto wmsParams = ConvertToWMSParam(panelFlag, params);
664     ret = AdjustLayout(wmsParams);
665     if (ret != ErrorCode::NO_ERROR) {
666         IMSA_HILOGE("AdjustKeyboardLayout error, err: %{public}d!", ret);
667         return ErrorCode::ERROR_WINDOW_MANAGER;
668     }
669     UpdateLayoutInfo(panelFlag, {}, params, wmsParams, true);
670     // set hot area
671     CalculateHotAreas(params, wmsParams, adjustInfo, hotAreas);
672     auto wmsHotAreas = ConvertToWMSHotArea(hotAreas);
673     auto result = window_->SetKeyboardTouchHotAreas(wmsHotAreas);
674     if (result != WMError::WM_OK) {
675         IMSA_HILOGE("SetKeyboardTouchHotAreas error, err: %{public}d!", result);
676         ret = AdjustLayout(lastWmsParam);
677         UpdateLayoutInfo(lastPanelFlag, {}, lastParams, lastWmsParam, lastIsEnhanced);
678         IMSA_HILOGE("restore layout param, result: %{public}d", ret);
679         return ErrorCode::ERROR_WINDOW_MANAGER;
680     }
681     SetHotAreas(hotAreas);
682     UpdateResizeParams();
683     IMSA_HILOGI("success, type/flag: %{public}d/%{public}d.", static_cast<int32_t>(panelType_),
684         static_cast<int32_t>(panelFlag_));
685     return ErrorCode::NO_ERROR;
686 }
687 
UpdateLayoutInfo(PanelFlag panelFlag,const LayoutParams & params,const EnhancedLayoutParams & enhancedParams,const KeyboardLayoutParams & wmsParams,bool isEnhanced)688 void InputMethodPanel::UpdateLayoutInfo(PanelFlag panelFlag, const LayoutParams &params,
689     const EnhancedLayoutParams &enhancedParams, const KeyboardLayoutParams &wmsParams, bool isEnhanced)
690 {
691     SetKeyboardLayoutParams(wmsParams);
692     if (isEnhanced) {
693         SetEnhancedLayoutParams(enhancedParams);
694     } else {
695         EnhancedLayoutParams enhancedLayoutParams = { .isFullScreen = false,
696             .portrait = { .rect = params.portraitRect },
697             .landscape = { .rect = params.landscapeRect } };
698         SetEnhancedLayoutParams(enhancedLayoutParams);
699     }
700     if (panelFlag_ != panelFlag) {
701         InputMethodAbility::GetInstance().NotifyPanelStatus(true, panelFlag);
702     }
703     panelFlag_ = panelFlag;
704     isInEnhancedAdjust_.store(isEnhanced);
705 }
706 
ParseEnhancedParams(PanelFlag panelFlag,const FullPanelAdjustInfo & adjustInfo,EnhancedLayoutParams & params)707 int32_t InputMethodPanel::ParseEnhancedParams(
708     PanelFlag panelFlag, const FullPanelAdjustInfo &adjustInfo, EnhancedLayoutParams &params)
709 {
710     DisplaySize display;
711     auto ret = GetDisplaySize(display);
712     if (ret != ErrorCode::NO_ERROR) {
713         IMSA_HILOGE("failed to GetDisplaySize ret: %{public}d", ret);
714         return ret;
715     }
716     ret = RectifyRect(params.isFullScreen, params.portrait, display.portrait, panelFlag, adjustInfo.portrait);
717     if (ret != ErrorCode::NO_ERROR) {
718         IMSA_HILOGE("RectifyRect portrait failed, ret: %{public}d", ret);
719         return ret;
720     }
721     ret = RectifyRect(params.isFullScreen, params.landscape, display.landscape, panelFlag, adjustInfo.landscape);
722     if (ret != ErrorCode::NO_ERROR) {
723         IMSA_HILOGE("RectifyRect landscape failed, ret: %{public}d", ret);
724         return ret;
725     }
726     ret = CalculateAvoidHeight(params.portrait, display.portrait, panelFlag, adjustInfo.portrait);
727     if (ret != ErrorCode::NO_ERROR) {
728         IMSA_HILOGE("CalculateAvoidHeight portrait failed, ret: %{public}d", ret);
729         return ret;
730     }
731     ret = CalculateAvoidHeight(params.landscape, display.landscape, panelFlag, adjustInfo.landscape);
732     if (ret != ErrorCode::NO_ERROR) {
733         IMSA_HILOGE("CalculateAvoidHeight landscape failed, ret: %{public}d", ret);
734         return ret;
735     }
736     IMSA_HILOGD("success, portrait: %{public}s, landscape: %{public}s", params.portrait.ToString().c_str(),
737         params.landscape.ToString().c_str());
738     return ErrorCode::NO_ERROR;
739 }
740 
IsRectValid(const Rosen::Rect & rect,const WindowSize & displaySize)741 bool InputMethodPanel::IsRectValid(const Rosen::Rect &rect, const WindowSize &displaySize)
742 {
743     if (rect.posX_ < 0 || rect.posY_ < 0) {
744         IMSA_HILOGE("posX_ and posY_ cannot be less than 0!");
745         return false;
746     }
747     if (rect.width_ > INT32_MAX || rect.height_ > INT32_MAX) {
748         IMSA_HILOGE("width or height over maximum!");
749         return false;
750     }
751     if (rect.width_ > displaySize.width || rect.height_ > displaySize.height) {
752         IMSA_HILOGE("invalid width or height, target: %{public}u/%{public}u, display: %{public}u/%{public}u",
753             rect.width_, rect.height_, displaySize.width, displaySize.height);
754         return false;
755     }
756     return true;
757 }
758 
IsRectValid(PanelFlag panelFlag,const Rosen::Rect & rect,const WindowSize & displaySize)759 bool InputMethodPanel::IsRectValid(PanelFlag panelFlag, const Rosen::Rect &rect, const WindowSize &displaySize)
760 {
761     if (rect.posX_ < 0 || rect.posY_ < 0) {
762         IMSA_HILOGE("posX_ and posY_ cannot be less than 0!");
763         return false;
764     }
765     return IsSizeValid(panelFlag, rect.width_, rect.height_, displaySize.width, displaySize.height);
766 }
767 
RectifyRect(bool isFullScreen,EnhancedLayoutParam & layoutParam,const WindowSize & displaySize,PanelFlag panelFlag,const PanelAdjustInfo & adjustInfo)768 int32_t InputMethodPanel::RectifyRect(bool isFullScreen, EnhancedLayoutParam &layoutParam,
769     const WindowSize &displaySize, PanelFlag panelFlag, const PanelAdjustInfo &adjustInfo)
770 {
771     if (isFullScreen) {
772         layoutParam.rect = { ORIGIN_POS_X, ORIGIN_POS_Y, displaySize.width, displaySize.height };
773         layoutParam.panelRect = layoutParam.rect;
774         return ErrorCode::NO_ERROR;
775     }
776     if (!IsRectValid(layoutParam.rect, displaySize)) {
777         return ErrorCode::ERROR_PARAMETER_CHECK_FAILED;
778     }
779     layoutParam.rect.height_ = std::max(layoutParam.rect.height_, static_cast<uint32_t>(adjustInfo.bottom));
780     if (panelFlag == PanelFlag::FLG_FIXED) {
781         layoutParam.rect = { FIXED_PANEL_POS_X, static_cast<int32_t>(displaySize.height - layoutParam.rect.height_),
782             displaySize.width, layoutParam.rect.height_ };
783     }
784     layoutParam.panelRect = layoutParam.rect;
785     return ErrorCode::NO_ERROR;
786 }
787 
CalculateAvoidHeight(EnhancedLayoutParam & layoutParam,const WindowSize & displaySize,PanelFlag panelFlag,const PanelAdjustInfo & adjustInfo)788 int32_t InputMethodPanel::CalculateAvoidHeight(EnhancedLayoutParam &layoutParam, const WindowSize &displaySize,
789     PanelFlag panelFlag, const PanelAdjustInfo &adjustInfo)
790 {
791     if (layoutParam.avoidY < 0 || layoutParam.avoidY > INT32_MAX) {
792         IMSA_HILOGE("invalid avoidY");
793         return ErrorCode::ERROR_PARAMETER_CHECK_FAILED;
794     }
795     if (static_cast<uint32_t>(layoutParam.avoidY) > layoutParam.rect.height_) {
796         IMSA_HILOGE(
797             "invalid avoidY %{public}d, keyboard height %{public}u", layoutParam.avoidY, layoutParam.rect.height_);
798         return ErrorCode::ERROR_PARAMETER_CHECK_FAILED;
799     }
800     auto ratio = panelFlag == PanelFlag::FLG_FIXED ? FIXED_SOFT_KEYBOARD_PANEL_RATIO
801                                                    : NON_FIXED_SOFT_KEYBOARD_PANEL_RATIO;
802     uint32_t avoidHeight = layoutParam.rect.height_ -  static_cast<uint32_t>(layoutParam.avoidY);
803     if (static_cast<float>(avoidHeight) > displaySize.height * ratio) {
804         IMSA_HILOGE("invalid avoidY: %{public}d, avoidHeight: %{public}u, displayHeight: %{public}u",
805             layoutParam.avoidY, avoidHeight, displaySize.height);
806         return ErrorCode::ERROR_PARAMETER_CHECK_FAILED;
807     }
808     if (avoidHeight < static_cast<uint32_t>(adjustInfo.bottom)) {
809         avoidHeight = adjustInfo.bottom;
810         layoutParam.avoidY = static_cast<int32_t>(layoutParam.rect.height_) - static_cast<int32_t>(avoidHeight);
811         IMSA_HILOGI("rectify avoidY to %{public}d", layoutParam.avoidY);
812     }
813     layoutParam.avoidHeight = avoidHeight;
814     return ErrorCode::NO_ERROR;
815 }
816 
UpdateHotAreas()817 void InputMethodPanel::UpdateHotAreas()
818 {
819     auto hotAreas = GetHotAreas();
820     if (!hotAreas.isSet) {
821         IMSA_HILOGD("hot area is not customized, no need to update");
822         return;
823     }
824     FullPanelAdjustInfo adjustInfo;
825     auto ret = GetAdjustInfo(panelFlag_, adjustInfo);
826     if (ret != ErrorCode::NO_ERROR) {
827         IMSA_HILOGE("GetAdjustInfo failed ret: %{public}d", ret);
828         return;
829     }
830     auto changeY = GetChangeY();
831     auto layoutParams = GetKeyboardLayoutParams();
832     CalculateDefaultHotArea(layoutParams.LandscapeKeyboardRect_, layoutParams.LandscapePanelRect_,
833         adjustInfo.landscape, hotAreas.landscape, changeY.landscape);
834     CalculateDefaultHotArea(layoutParams.PortraitKeyboardRect_, layoutParams.PortraitPanelRect_, adjustInfo.portrait,
835         hotAreas.portrait, changeY.portrait);
836     auto wmsHotAreas = ConvertToWMSHotArea(hotAreas);
837     WMError result = window_->SetKeyboardTouchHotAreas(wmsHotAreas);
838     if (result != WMError::WM_OK) {
839         IMSA_HILOGE("SetKeyboardTouchHotAreas error, err: %{public}d!", result);
840         return;
841     }
842     SetHotAreas(hotAreas);
843     IMSA_HILOGI("success, portrait: %{public}s, landscape: %{public}s",
844         HotArea::ToString(hotAreas.portrait.keyboardHotArea).c_str(),
845         HotArea::ToString(hotAreas.landscape.keyboardHotArea).c_str());
846 }
847 
CalculateHotAreas(const EnhancedLayoutParams & enhancedParams,const Rosen::KeyboardLayoutParams & params,const FullPanelAdjustInfo & adjustInfo,HotAreas & hotAreas)848 void InputMethodPanel::CalculateHotAreas(const EnhancedLayoutParams &enhancedParams,
849     const Rosen::KeyboardLayoutParams &params, const FullPanelAdjustInfo &adjustInfo, HotAreas &hotAreas)
850 {
851     auto changeY = GetChangeY();
852     if (isInEnhancedAdjust_.load()) {
853         CalculateEnhancedHotArea(enhancedParams.portrait, adjustInfo.portrait, hotAreas.portrait, changeY.portrait);
854         CalculateEnhancedHotArea(enhancedParams.landscape, adjustInfo.landscape, hotAreas.landscape, changeY.landscape);
855     } else {
856         CalculateHotArea(params.PortraitKeyboardRect_, params.PortraitPanelRect_, adjustInfo.portrait,
857             hotAreas.portrait, changeY.portrait);
858         CalculateHotArea(params.LandscapeKeyboardRect_, params.LandscapePanelRect_, adjustInfo.landscape,
859             hotAreas.landscape, changeY.landscape);
860     }
861     hotAreas.isSet = true;
862     IMSA_HILOGD("portrait keyboard: %{public}s, panel: %{public}s",
863         HotArea::ToString(hotAreas.portrait.keyboardHotArea).c_str(),
864         HotArea::ToString(hotAreas.portrait.panelHotArea).c_str());
865     IMSA_HILOGD("landscape keyboard: %{public}s, panel: %{public}s",
866         HotArea::ToString(hotAreas.landscape.keyboardHotArea).c_str(),
867         HotArea::ToString(hotAreas.landscape.panelHotArea).c_str());
868 }
869 
CalculateHotArea(const Rosen::Rect & keyboard,const Rosen::Rect & panel,const PanelAdjustInfo & adjustInfo,HotArea & hotArea,uint32_t changeY)870 void InputMethodPanel::CalculateHotArea(const Rosen::Rect &keyboard, const Rosen::Rect &panel,
871     const PanelAdjustInfo &adjustInfo, HotArea &hotArea, uint32_t changeY)
872 {
873     IMSA_HILOGI("changeY: %{public}u", changeY);
874     // calculate keyboard hot area
875     if (hotArea.keyboardHotArea.empty()) {
876         hotArea.keyboardHotArea.push_back({ ORIGIN_POS_X, ORIGIN_POS_Y, keyboard.width_, keyboard.height_ });
877     }
878     std::vector<Rosen::Rect> availableAreas = { { { ORIGIN_POS_X, ORIGIN_POS_Y, keyboard.width_, keyboard.height_ } } };
879     RectifyAreas(availableAreas, hotArea.keyboardHotArea);
880     // calculate panel hot area
881     Rosen::Rect left = { ORIGIN_POS_X, ORIGIN_POS_Y + static_cast<int32_t>(changeY),
882         static_cast<uint32_t>(adjustInfo.left), panel.height_ };
883     Rosen::Rect right = { .posX_ = static_cast<int32_t>(panel.width_) - adjustInfo.right,
884         .posY_ = ORIGIN_POS_Y + static_cast<int32_t>(changeY),
885         .width_ = static_cast<uint32_t>(adjustInfo.right),
886         .height_ = panel.height_ };
887     Rosen::Rect bottom = { .posX_ = ORIGIN_POS_X,
888         .posY_ = static_cast<int32_t>(panel.height_ + changeY) - adjustInfo.bottom,
889         .width_ = panel.width_,
890         .height_ = static_cast<uint32_t>(adjustInfo.bottom) };
891     hotArea.panelHotArea = { left, right, bottom };
892 }
893 
CalculateEnhancedHotArea(const EnhancedLayoutParam & layout,const PanelAdjustInfo & adjustInfo,HotArea & hotArea,uint32_t changeY)894 void InputMethodPanel::CalculateEnhancedHotArea(
895     const EnhancedLayoutParam &layout, const PanelAdjustInfo &adjustInfo, HotArea &hotArea, uint32_t changeY)
896 {
897     IMSA_HILOGI("changeY: %{public}u", changeY);
898     // calculate keyboard hot area
899     if (hotArea.keyboardHotArea.empty()) {
900         hotArea.keyboardHotArea.push_back({ ORIGIN_POS_X, ORIGIN_POS_Y, layout.rect.width_, layout.rect.height_ });
901     }
902     std::vector<Rosen::Rect> availableAreas;
903     availableAreas.push_back({ ORIGIN_POS_X, ORIGIN_POS_Y, layout.rect.width_, static_cast<uint32_t>(layout.avoidY) });
904     availableAreas.push_back({ .posX_ = adjustInfo.left,
905         .posY_ = layout.avoidY,
906         .width_ = SafeSubtract(layout.rect.width_, static_cast<uint32_t>(adjustInfo.left + adjustInfo.right)),
907         .height_ = SafeSubtract(layout.avoidHeight, static_cast<uint32_t>(adjustInfo.bottom)) });
908     RectifyAreas(availableAreas, hotArea.keyboardHotArea);
909     // calculate panel hot area
910     Rosen::Rect left = { ORIGIN_POS_X, layout.avoidY + static_cast<int32_t>(changeY),
911         static_cast<uint32_t>(adjustInfo.left), layout.avoidHeight };
912     Rosen::Rect right = { .posX_ = static_cast<int32_t>(layout.rect.width_) - adjustInfo.right,
913         .posY_ = layout.avoidY + static_cast<int32_t>(changeY),
914         .width_ = static_cast<uint32_t>(adjustInfo.right),
915         .height_ = layout.avoidHeight };
916     Rosen::Rect bottom = { .posX_ = ORIGIN_POS_X,
917         .posY_ = static_cast<int32_t>(layout.rect.height_ + changeY) - adjustInfo.bottom,
918         .width_ = layout.rect.width_,
919         .height_ = static_cast<uint32_t>(adjustInfo.bottom) };
920     hotArea.panelHotArea = { left, right, bottom };
921 }
922 
CalculateDefaultHotArea(const Rosen::Rect & keyboard,const Rosen::Rect & panel,const PanelAdjustInfo & adjustInfo,HotArea & hotArea,uint32_t changeY)923 void InputMethodPanel::CalculateDefaultHotArea(const Rosen::Rect &keyboard, const Rosen::Rect &panel,
924     const PanelAdjustInfo &adjustInfo, HotArea &hotArea, uint32_t changeY)
925 {
926     IMSA_HILOGI("changeY: %{public}u", changeY);
927     // calculate keyboard hot area
928     hotArea.keyboardHotArea.clear();
929     hotArea.keyboardHotArea.push_back({ ORIGIN_POS_X, ORIGIN_POS_Y, keyboard.width_, keyboard.height_ });
930     // calculate panel hot area
931     Rosen::Rect left = { ORIGIN_POS_X, ORIGIN_POS_Y + static_cast<int32_t>(changeY),
932         static_cast<uint32_t>(adjustInfo.left), panel.height_ };
933     Rosen::Rect right = { .posX_ = static_cast<int32_t>(panel.width_) - adjustInfo.right,
934         .posY_ = ORIGIN_POS_Y + static_cast<int32_t>(changeY),
935         .width_ = static_cast<uint32_t>(adjustInfo.right),
936         .height_ = panel.height_ };
937     Rosen::Rect bottom = { .posX_ = ORIGIN_POS_X,
938         .posY_ = static_cast<int32_t>(panel.height_ + changeY) - adjustInfo.bottom,
939         .width_ = panel.width_,
940         .height_ = static_cast<uint32_t>(adjustInfo.bottom) };
941     hotArea.panelHotArea = { left, right, bottom };
942 }
943 
RectifyAreas(const std::vector<Rosen::Rect> & availableAreas,std::vector<Rosen::Rect> & areas)944 void InputMethodPanel::RectifyAreas(const std::vector<Rosen::Rect> &availableAreas, std::vector<Rosen::Rect> &areas)
945 {
946     std::vector<Rosen::Rect> validAreas;
947     for (const auto &availableArea : availableAreas) {
948         std::vector<Rosen::Rect> modifiedAreas;
949         for (const auto &area : areas) {
950             auto inter = GetRectIntersection(area, availableArea);
951             if (inter.width_ != 0 && inter.height_ != 0) {
952                 modifiedAreas.push_back(inter);
953             }
954         }
955         validAreas.insert(validAreas.end(), modifiedAreas.begin(), modifiedAreas.end());
956     }
957     areas = std::move(validAreas);
958     // If no valid area, set the region size to 0.
959     if (areas.empty()) {
960         areas.push_back({ 0, 0, 0, 0 });
961     }
962 }
963 
GetRectIntersection(Rosen::Rect a,Rosen::Rect b)964 Rosen::Rect InputMethodPanel::GetRectIntersection(Rosen::Rect a, Rosen::Rect b)
965 {
966     int32_t left = std::max(a.posX_, b.posX_);
967     int32_t right = std::min(a.posX_ + static_cast<int32_t>(a.width_), b.posX_ + static_cast<int32_t>(b.width_));
968     int32_t top = std::max(a.posY_, b.posY_);
969     int32_t bottom = std::min(a.posY_ + static_cast<int32_t>(a.height_), b.posY_ + static_cast<int32_t>(b.height_));
970     if (left < right && top < bottom) {
971         return { left, top, static_cast<uint32_t>(right - left), static_cast<uint32_t>(bottom - top) };
972     } else {
973         return { 0, 0, 0, 0 };
974     }
975 }
976 
SafeSubtract(uint32_t minuend,uint32_t subtrahend)977 uint32_t InputMethodPanel::SafeSubtract(uint32_t minuend, uint32_t subtrahend)
978 {
979     if (minuend < subtrahend) {
980         IMSA_HILOGE("subtrahend:%{public}u is larger than minuend:%{public}u", subtrahend, minuend);
981         return 0;
982     }
983     return minuend - subtrahend;
984 }
985 
UpdateRegion(std::vector<Rosen::Rect> region)986 int32_t InputMethodPanel::UpdateRegion(std::vector<Rosen::Rect> region)
987 {
988     if (window_ == nullptr) {
989         IMSA_HILOGE("window_ is nullptr!");
990         return ErrorCode::ERROR_WINDOW_MANAGER;
991     }
992     if (panelType_ != PanelType::SOFT_KEYBOARD) {
993         IMSA_HILOGE("not soft keyboard panel: %{public}d", panelType_);
994         return ErrorCode::ERROR_INVALID_PANEL_TYPE;
995     }
996     if (panelFlag_ != PanelFlag::FLG_FIXED && panelFlag_ != PanelFlag::FLG_FLOATING) {
997         IMSA_HILOGE("flag not fixed or floating: %{public}d", panelFlag_);
998         return ErrorCode::ERROR_INVALID_PANEL_FLAG;
999     }
1000     FullPanelAdjustInfo adjustInfo;
1001     auto ret = GetAdjustInfo(panelFlag_, adjustInfo);
1002     if (ret != ErrorCode::NO_ERROR) {
1003         IMSA_HILOGE("GetAdjustInfo failed ret: %{public}d", ret);
1004         return ret;
1005     }
1006     IMSA_HILOGD("region: %{public}s", HotArea::ToString(region).c_str());
1007     auto hotAreas = GetHotAreas();
1008     bool isPortrait = IsDisplayPortrait();
1009     if (isPortrait) {
1010         hotAreas.portrait.keyboardHotArea = region;
1011     } else {
1012         hotAreas.landscape.keyboardHotArea = region;
1013     }
1014     CalculateHotAreas(GetEnhancedLayoutParams(), GetKeyboardLayoutParams(), adjustInfo, hotAreas);
1015     auto wmsHotAreas = ConvertToWMSHotArea(hotAreas);
1016     WMError result = window_->SetKeyboardTouchHotAreas(wmsHotAreas);
1017     if (result != WMError::WM_OK) {
1018         IMSA_HILOGE("SetKeyboardTouchHotAreas error, err: %{public}d!", result);
1019         return ErrorCode::ERROR_WINDOW_MANAGER;
1020     }
1021     SetHotAreas(hotAreas);
1022     if (isPortrait) {
1023         IMSA_HILOGI("success, portrait: %{public}s", HotArea::ToString(hotAreas.portrait.keyboardHotArea).c_str());
1024     } else {
1025         IMSA_HILOGI("success, landscape: %{public}s", HotArea::ToString(hotAreas.landscape.keyboardHotArea).c_str());
1026     }
1027     return ErrorCode::NO_ERROR;
1028 }
1029 
InitAdjustInfo()1030 int32_t InputMethodPanel::InitAdjustInfo()
1031 {
1032     std::lock_guard<std::mutex> initLk(adjustInfoInitLock_);
1033     auto curDisplayId = GetCurDisplayId();
1034     if (isAdjustInfoInitialized_.load() && adjustInfoDisplayId_ == curDisplayId) {
1035         return ErrorCode::NO_ERROR;
1036     }
1037     std::vector<SysPanelAdjust> configs;
1038     auto isSuccess = SysCfgParser::ParsePanelAdjust(configs);
1039     if (!isSuccess) {
1040         adjustInfoDisplayId_ = curDisplayId;
1041         isAdjustInfoInitialized_.store(true);
1042         return ErrorCode::NO_ERROR;
1043     }
1044     float densityDpi = 0;
1045     if (GetDensityDpi(densityDpi) != ErrorCode::NO_ERROR) {
1046         IMSA_HILOGE("failed to get density dpi");
1047         return ErrorCode::ERROR_WINDOW_MANAGER;
1048     }
1049     std::lock_guard<std::mutex> lk(panelAdjustLock_);
1050     panelAdjust_.clear();
1051     for (const auto &config : configs) {
1052         PanelAdjustInfo info = {
1053             .top = static_cast<int32_t>(config.top * densityDpi),
1054             .left = static_cast<int32_t>(config.left * densityDpi),
1055             .right = static_cast<int32_t>(config.right * densityDpi),
1056             .bottom = static_cast<int32_t>(config.bottom * densityDpi) };
1057         panelAdjust_.insert({ config.style, info });
1058     }
1059     adjustInfoDisplayId_ = curDisplayId;
1060     isAdjustInfoInitialized_.store(true);
1061     return ErrorCode::NO_ERROR;
1062 }
1063 
ParseParams(PanelFlag panelFlag,const LayoutParams & input,KeyboardLayoutParams & output)1064 int32_t InputMethodPanel::ParseParams(PanelFlag panelFlag, const LayoutParams &input, KeyboardLayoutParams &output)
1065 {
1066     // 1 - check parameters
1067     DisplaySize displaySize;
1068     int32_t ret = GetDisplaySize(displaySize);
1069     if (ret != ErrorCode::NO_ERROR) {
1070         IMSA_HILOGE("failed to GetDisplaySize ret: %{public}d", ret);
1071         return ErrorCode::ERROR_WINDOW_MANAGER;
1072     }
1073     if (!IsRectValid(panelFlag, input.portraitRect, displaySize.portrait)) {
1074         IMSA_HILOGE("invalid portrait rect!");
1075         return ErrorCode::ERROR_PARAMETER_CHECK_FAILED;
1076     }
1077     if (!IsRectValid(panelFlag, input.landscapeRect, displaySize.landscape)) {
1078         IMSA_HILOGE("invalid landscape rect!");
1079         return ErrorCode::ERROR_PARAMETER_CHECK_FAILED;
1080     }
1081 
1082     // 2 - calculate parameters
1083     FullPanelAdjustInfo adjustInfo;
1084     if (IsNeedConfig()) {
1085         ret = GetAdjustInfo(panelFlag, adjustInfo);
1086         IMSA_HILOGD("get adjust info: %{public}d", ret);
1087     }
1088     EnhancedLayoutParams tempOutput;
1089     ParseParam(panelFlag, adjustInfo.portrait, displaySize.portrait, input.portraitRect, tempOutput.portrait);
1090     ParseParam(panelFlag, adjustInfo.landscape, displaySize.landscape, input.landscapeRect, tempOutput.landscape);
1091     output = ConvertToWMSParam(panelFlag, tempOutput);
1092     output.portraitAvoidHeight_ = DEFAULT_AVOID_HEIGHT;
1093     output.landscapeAvoidHeight_ = DEFAULT_AVOID_HEIGHT;
1094     IMSA_HILOGD("success, portrait: %{public}s, landscape: %{public}s", tempOutput.portrait.ToString().c_str(),
1095         tempOutput.landscape.ToString().c_str());
1096     return ErrorCode::NO_ERROR;
1097 }
1098 
ParseParam(PanelFlag panelFlag,const PanelAdjustInfo & adjustInfo,const WindowSize & displaySize,const Rosen::Rect & inputRect,EnhancedLayoutParam & outputParam)1099 void InputMethodPanel::ParseParam(PanelFlag panelFlag, const PanelAdjustInfo &adjustInfo,
1100     const WindowSize &displaySize, const Rosen::Rect &inputRect, EnhancedLayoutParam &outputParam)
1101 {
1102     Rosen::Rect panelRect{};
1103     Rosen::Rect keyboardRect{};
1104     if (panelFlag == PanelFlag::FLG_FIXED) {
1105         // fixed panel rect
1106         panelRect.width_ = displaySize.width;
1107         panelRect.height_ = inputRect.height_ + static_cast<uint32_t>(adjustInfo.top + adjustInfo.bottom);
1108         panelRect.height_ = std::min(panelRect.height_,
1109             static_cast<uint32_t>(static_cast<float>(displaySize.height) * FIXED_SOFT_KEYBOARD_PANEL_RATIO));
1110         panelRect.posX_ = ORIGIN_POS_X;
1111         panelRect.posY_ = static_cast<int32_t>(SafeSubtract(displaySize.height, panelRect.height_));
1112         // fixed keyboard rect
1113         keyboardRect.width_ =
1114             SafeSubtract(panelRect.width_, static_cast<uint32_t>(adjustInfo.left + adjustInfo.right));
1115         keyboardRect.height_ =
1116             SafeSubtract(panelRect.height_, static_cast<uint32_t>(adjustInfo.top + adjustInfo.bottom));
1117         keyboardRect.posY_ = panelRect.posY_ + static_cast<int32_t>(adjustInfo.top);
1118         keyboardRect.posX_ = panelRect.posX_ + static_cast<int32_t>(adjustInfo.left);
1119     } else {
1120         // floating keyboard rect
1121         keyboardRect = inputRect;
1122         // floating panel rect
1123         panelRect.width_ = keyboardRect.width_ + static_cast<uint32_t>(adjustInfo.left + adjustInfo.right);
1124         panelRect.height_ = keyboardRect.height_ + static_cast<uint32_t>(adjustInfo.top + adjustInfo.bottom);
1125         panelRect.posY_ = keyboardRect.posY_ - adjustInfo.top;
1126         panelRect.posX_ = keyboardRect.posX_ - adjustInfo.left;
1127     }
1128     outputParam.rect = keyboardRect;
1129     outputParam.panelRect = panelRect;
1130 }
1131 
GetScreenStatus(const PanelFlag panelFlag)1132 std::tuple<std::vector<std::string>, std::vector<std::string>> InputMethodPanel::GetScreenStatus(
1133     const PanelFlag panelFlag)
1134 {
1135     std::string flag = "invaildFlag";
1136     std::string foldStatus = "default";
1137     if (panelFlag == PanelFlag::FLG_FIXED) {
1138         flag = "fix";
1139     } else if (panelFlag == PanelFlag::FLG_FLOATING) {
1140         flag = "floating";
1141     }
1142     if (Rosen::DisplayManager::GetInstance().IsFoldable() &&
1143         Rosen::DisplayManager::GetInstance().GetFoldStatus() != Rosen::FoldStatus::FOLDED) {
1144         foldStatus = "foldable";
1145     }
1146     std::vector<std::string> lanPanel = { flag, foldStatus, "landscape" };
1147     std::vector<std::string> porPanel = { flag, foldStatus, "portrait" };
1148     return std::make_tuple(lanPanel, porPanel);
1149 }
1150 
GetAdjustInfo(PanelFlag panelFlag,FullPanelAdjustInfo & fullPanelAdjustInfo)1151 int32_t InputMethodPanel::GetAdjustInfo(PanelFlag panelFlag, FullPanelAdjustInfo &fullPanelAdjustInfo)
1152 {
1153     int32_t ret = InitAdjustInfo();
1154     if (ret != ErrorCode::NO_ERROR) {
1155         IMSA_HILOGE("failed to init adjust info, ret: %{public}d", ret);
1156         return ret;
1157     }
1158     auto keys = GetScreenStatus(panelFlag);
1159     auto landscapeKey = std::get<0>(keys);
1160     auto portraitKey = std::get<1>(keys);
1161     std::lock_guard<std::mutex> lock(panelAdjustLock_);
1162     auto lanIter = panelAdjust_.find(landscapeKey);
1163     auto porIter = panelAdjust_.find(portraitKey);
1164     if (lanIter != panelAdjust_.end()) {
1165         fullPanelAdjustInfo.landscape = lanIter->second;
1166     }
1167     if (porIter != panelAdjust_.end()) {
1168         fullPanelAdjustInfo.portrait = porIter->second;
1169     }
1170     IMSA_HILOGD("GetAdjustInfo, portrait: %{public}s, landscape: %{public}s",
1171         fullPanelAdjustInfo.portrait.ToString().c_str(), fullPanelAdjustInfo.landscape.ToString().c_str());
1172     return ErrorCode::NO_ERROR;
1173 }
1174 
ChangePanelFlag(PanelFlag panelFlag)1175 int32_t InputMethodPanel::ChangePanelFlag(PanelFlag panelFlag)
1176 {
1177     if (window_ == nullptr) {
1178         IMSA_HILOGE("window_ is nullptr!");
1179         return ErrorCode::ERROR_NULL_POINTER;
1180     }
1181     if (panelFlag_ == panelFlag) {
1182         return ErrorCode::NO_ERROR;
1183     }
1184     if (panelType_ == STATUS_BAR) {
1185         IMSA_HILOGE("STATUS_BAR cannot ChangePanelFlag!");
1186         return ErrorCode::ERROR_BAD_PARAMETERS;
1187     }
1188     if (panelType_ == SOFT_KEYBOARD && panelFlag == FLG_CANDIDATE_COLUMN) {
1189         PanelStatusChangeToImc(InputWindowStatus::HIDE, { 0, 0, 0, 0 });
1190     }
1191     WindowGravity gravity = WindowGravity::WINDOW_GRAVITY_FLOAT;
1192     if (panelFlag == FLG_FIXED) {
1193         gravity = WindowGravity::WINDOW_GRAVITY_BOTTOM;
1194     } else {
1195         auto surfaceNode = window_->GetSurfaceNode();
1196         if (surfaceNode == nullptr) {
1197             IMSA_HILOGE("surfaceNode is nullptr!");
1198             return ErrorCode::ERROR_NULL_POINTER;
1199         }
1200         surfaceNode->SetFrameGravity(Rosen::Gravity::TOP_LEFT);
1201         Rosen::RSTransactionProxy::GetInstance()->FlushImplicitTransaction();
1202     }
1203     if (!isScbEnable_) {
1204         auto ret = window_->SetWindowGravity(gravity, invalidGravityPercent);
1205         if (ret == WMError::WM_OK) {
1206             panelFlag_ = panelFlag;
1207         }
1208         IMSA_HILOGI("flag: %{public}d, ret: %{public}d.", panelFlag, ret);
1209         return ret == WMError::WM_OK ? ErrorCode::NO_ERROR : ErrorCode::ERROR_OPERATE_PANEL;
1210     }
1211     auto layoutParams = GetKeyboardLayoutParams();
1212     layoutParams.gravity_ = gravity;
1213     auto ret = AdjustLayout(layoutParams);
1214     if (ret == ErrorCode::NO_ERROR) {
1215         panelFlag_ = panelFlag;
1216         SetKeyboardLayoutParams(layoutParams);
1217     }
1218     InputMethodAbility::GetInstance().NotifyPanelStatus(true, panelFlag);
1219     IMSA_HILOGI("flag: %{public}d, ret: %{public}d.", panelFlag, ret);
1220     return ret == ErrorCode::NO_ERROR ? ErrorCode::NO_ERROR : ErrorCode::ERROR_OPERATE_PANEL;
1221 }
1222 
GetPanelType()1223 PanelType InputMethodPanel::GetPanelType()
1224 {
1225     return panelType_;
1226 }
1227 
GetPanelFlag()1228 PanelFlag InputMethodPanel::GetPanelFlag()
1229 {
1230     return panelFlag_;
1231 }
1232 
ShowPanel()1233 int32_t InputMethodPanel::ShowPanel()
1234 {
1235     IMSA_HILOGD("InputMethodPanel start.");
1236     int32_t waitTime = 0;
1237     while (isWaitSetUiContent_ && waitTime < MAXWAITTIME) {
1238         std::this_thread::sleep_for(std::chrono::milliseconds(WAITTIME));
1239         waitTime += WAITTIME;
1240         IMSA_HILOGI("InputMethodPanel show pannel waitTime %{public}d.", waitTime);
1241     }
1242     if (window_ == nullptr) {
1243         IMSA_HILOGE("window_ is nullptr!");
1244         return ErrorCode::ERROR_IMA_NULLPTR;
1245     }
1246     if (IsShowing()) {
1247         IMSA_HILOGI("panel already shown.");
1248         return ErrorCode::NO_ERROR;
1249     }
1250     auto ret = WMError::WM_OK;
1251     {
1252         KeyboardEffectOption option = ConvertToWmEffect(GetImmersiveMode(), LoadImmersiveEffect());
1253         InputMethodSyncTrace tracer("InputMethodPanel_ShowPanel");
1254         ret = window_->ShowKeyboard(option);
1255     }
1256     if (ret != WMError::WM_OK) {
1257         IMSA_HILOGE("ShowPanel error, err = %{public}d", ret);
1258         return ErrorCode::ERROR_OPERATE_PANEL;
1259     }
1260     IMSA_HILOGI("success, type/flag: %{public}d/%{public}d.", static_cast<int32_t>(panelType_),
1261         static_cast<int32_t>(panelFlag_));
1262     PanelStatusChange(InputWindowStatus::SHOW);
1263     if (!isScbEnable_) {
1264         PanelStatusChangeToImc(InputWindowStatus::SHOW, window_->GetRect());
1265     }
1266     return ErrorCode::NO_ERROR;
1267 }
1268 
SetTextFieldAvoidInfo(double positionY,double height)1269 int32_t InputMethodPanel::SetTextFieldAvoidInfo(double positionY, double height)
1270 {
1271     if (window_ == nullptr) {
1272         IMSA_HILOGE("window_ is nullptr!");
1273         return ErrorCode::ERROR_NULL_POINTER;
1274     }
1275     auto ret = window_->SetTextFieldAvoidInfo(positionY, height);
1276     if (ret != WMError::WM_OK) {
1277         IMSA_HILOGE("SetTextFieldAvoidInfo error, err: %{public}d!", ret);
1278         return ErrorCode::ERROR_OPERATE_PANEL;
1279     }
1280     return ErrorCode::NO_ERROR;
1281 }
1282 
HidePanel()1283 int32_t InputMethodPanel::HidePanel()
1284 {
1285     IMSA_HILOGD("InputMethodPanel start");
1286     if (window_ == nullptr) {
1287         IMSA_HILOGE("window_ is nullptr!");
1288         return ErrorCode::ERROR_NULL_POINTER;
1289     }
1290     if (IsHidden()) {
1291         IMSA_HILOGI("panel already hidden.");
1292         return ErrorCode::NO_ERROR;
1293     }
1294     auto ret = WMError::WM_OK;
1295     {
1296         InputMethodSyncTrace tracer("InputMethodPanel_HidePanel");
1297         ret = window_->Hide();
1298     }
1299     if (ret != WMError::WM_OK) {
1300         IMSA_HILOGE("HidePanel error, err: %{public}d!", ret);
1301         return ErrorCode::ERROR_OPERATE_PANEL;
1302     }
1303     IMSA_HILOGI("success, type/flag: %{public}d/%{public}d.", static_cast<int32_t>(panelType_),
1304         static_cast<int32_t>(panelFlag_));
1305     PanelStatusChange(InputWindowStatus::HIDE);
1306     if (!isScbEnable_) {
1307         PanelStatusChangeToImc(InputWindowStatus::HIDE, { 0, 0, 0, 0 });
1308     }
1309     return ErrorCode::NO_ERROR;
1310 }
1311 
SetCallingWindow(uint32_t windowId)1312 int32_t InputMethodPanel::SetCallingWindow(uint32_t windowId)
1313 {
1314     IMSA_HILOGD("InputMethodPanel start, windowId: %{public}d.", windowId);
1315     if (window_ == nullptr) {
1316         IMSA_HILOGE("window_ is nullptr!");
1317         return ErrorCode::ERROR_PANEL_NOT_FOUND;
1318     }
1319     auto ret = window_->SetCallingWindow(windowId);
1320     IMSA_HILOGI("ret: %{public}d, windowId: %{public}u", ret, windowId);
1321     return ret == WMError::WM_OK ? ErrorCode::NO_ERROR : ErrorCode::ERROR_WINDOW_MANAGER;
1322 }
1323 
GetCallingWindowInfo(CallingWindowInfo & windowInfo)1324 int32_t InputMethodPanel::GetCallingWindowInfo(CallingWindowInfo &windowInfo)
1325 {
1326     IMSA_HILOGD("InputMethodPanel start.");
1327     if (window_ == nullptr) {
1328         IMSA_HILOGE("window_ is nullptr!");
1329         return ErrorCode::ERROR_PANEL_NOT_FOUND;
1330     }
1331     auto ret = window_->GetCallingWindowWindowStatus(windowInfo.status);
1332     if (ret != WMError::WM_OK) {
1333         IMSA_HILOGE("get status failed, ret: %{public}d!", ret);
1334         return ErrorCode::ERROR_WINDOW_MANAGER;
1335     }
1336     ret = window_->GetCallingWindowRect(windowInfo.rect);
1337     if (ret != WMError::WM_OK) {
1338         IMSA_HILOGE("get rect failed, ret: %{public}d!", ret);
1339         return ErrorCode::ERROR_WINDOW_MANAGER;
1340     }
1341     IMSA_HILOGI("status: %{public}u, rect[x/y/w/h]: [%{public}d/%{public}d/%{public}u/%{public}u].",
1342         static_cast<uint32_t>(windowInfo.status), windowInfo.rect.posX_, windowInfo.rect.posY_, windowInfo.rect.width_,
1343         windowInfo.rect.height_);
1344     return ErrorCode::NO_ERROR;
1345 }
1346 
SetPrivacyMode(bool isPrivacyMode)1347 int32_t InputMethodPanel::SetPrivacyMode(bool isPrivacyMode)
1348 {
1349     IMSA_HILOGD("isPrivacyMode: %{public}d.", isPrivacyMode);
1350     if (window_ == nullptr) {
1351         IMSA_HILOGE("window_ is nullptr!");
1352         return ErrorCode::ERROR_NULL_POINTER;
1353     }
1354     auto ret = window_->SetPrivacyMode(isPrivacyMode);
1355     if (ret != WMError::WM_OK) {
1356         IMSA_HILOGE("SetWindowPrivacyMode error, ret: %{public}d", ret);
1357         return static_cast<int32_t>(ret);
1358     }
1359     IMSA_HILOGD("end, isPrivacyMode: %{public}d.", isPrivacyMode);
1360     return ErrorCode::NO_ERROR;
1361 }
1362 
PanelStatusChange(const InputWindowStatus & status)1363 void InputMethodPanel::PanelStatusChange(const InputWindowStatus &status)
1364 {
1365     if (status == InputWindowStatus::SHOW && showRegistered_ && panelStatusListener_ != nullptr) {
1366         IMSA_HILOGD("ShowPanel panelStatusListener_ is not nullptr.");
1367         panelStatusListener_->OnPanelStatus(windowId_, true);
1368     }
1369     if (status == InputWindowStatus::HIDE && hideRegistered_ && panelStatusListener_ != nullptr) {
1370         IMSA_HILOGD("HidePanel panelStatusListener_ is not nullptr.");
1371         panelStatusListener_->OnPanelStatus(windowId_, false);
1372     }
1373 }
1374 
PanelStatusChangeToImc(const InputWindowStatus & status,const Rosen::Rect & rect)1375 void InputMethodPanel::PanelStatusChangeToImc(const InputWindowStatus &status, const Rosen::Rect &rect)
1376 {
1377     ImeWindowInfo info;
1378     info.panelInfo.panelType = panelType_;
1379     info.panelInfo.panelFlag = panelFlag_;
1380     if (info.panelInfo.panelType != SOFT_KEYBOARD || info.panelInfo.panelFlag == FLG_CANDIDATE_COLUMN) {
1381         IMSA_HILOGD("no need to deal.");
1382         return;
1383     }
1384     auto proxy = ImaUtils::GetImsaProxy();
1385     if (proxy == nullptr) {
1386         IMSA_HILOGE("proxy is nullptr!");
1387         return;
1388     }
1389 
1390     if (window_ == nullptr) {
1391         IMSA_HILOGE("window_ is nullptr!");
1392         return;
1393     }
1394 
1395     std::string name = window_->GetWindowName() + "/" + std::to_string(window_->GetWindowId());
1396     info.windowInfo.name = std::move(name);
1397     info.windowInfo.left = rect.posX_;
1398     info.windowInfo.top = rect.posY_;
1399     info.windowInfo.width = rect.width_;
1400     info.windowInfo.height = rect.height_;
1401     IMSA_HILOGD("rect[%{public}d, %{public}d, %{public}u, %{public}u], status: %{public}d, "
1402                 "panelFlag: %{public}d.",
1403         rect.posX_, rect.posY_, rect.width_, rect.height_, status, info.panelInfo.panelFlag);
1404     proxy->PanelStatusChange(static_cast<uint32_t>(status), info);
1405 }
1406 
IsShowing()1407 bool InputMethodPanel::IsShowing()
1408 {
1409     if (window_ == nullptr) {
1410         IMSA_HILOGE("window_ is nullptr!");
1411         return false;
1412     }
1413     auto windowState = window_->GetWindowState();
1414     if (windowState == WindowState::STATE_SHOWN) {
1415         return true;
1416     }
1417     IMSA_HILOGD("windowState: %{public}d.", static_cast<int>(windowState));
1418     return false;
1419 }
1420 
IsHidden()1421 bool InputMethodPanel::IsHidden()
1422 {
1423     auto windowState = window_->GetWindowState();
1424     if (windowState == WindowState::STATE_HIDDEN) {
1425         return true;
1426     }
1427     IMSA_HILOGD("windowState: %{public}d.", static_cast<int>(windowState));
1428     return false;
1429 }
1430 
SetUiContent(const std::string & contentInfo,napi_env env,std::shared_ptr<NativeReference> storage)1431 int32_t InputMethodPanel::SetUiContent(
1432     const std::string &contentInfo, napi_env env, std::shared_ptr<NativeReference> storage)
1433 {
1434     if (window_ == nullptr) {
1435         IMSA_HILOGE("window_ is nullptr, can not SetUiContent!");
1436         return ErrorCode::ERROR_NULL_POINTER;
1437     }
1438     WMError ret = WMError::WM_OK;
1439     if (storage == nullptr) {
1440         ret = window_->NapiSetUIContent(contentInfo, env, nullptr);
1441     } else {
1442         ret = window_->NapiSetUIContent(contentInfo, env, storage->GetNapiValue());
1443     }
1444     WMError wmError = window_->SetTransparent(true);
1445     if (isWaitSetUiContent_) {
1446         isWaitSetUiContent_ = false;
1447     }
1448     IMSA_HILOGI("SetTransparent ret: %{public}u.", wmError);
1449     IMSA_HILOGI("NapiSetUIContent ret: %{public}d.", ret);
1450     return ret == WMError::WM_ERROR_INVALID_PARAM ? ErrorCode::ERROR_PARAMETER_CHECK_FAILED : ErrorCode::NO_ERROR;
1451 }
1452 
SetPanelStatusListener(std::shared_ptr<PanelStatusListener> statusListener,const std::string & type)1453 bool InputMethodPanel::SetPanelStatusListener(
1454     std::shared_ptr<PanelStatusListener> statusListener, const std::string &type)
1455 {
1456     if (!MarkListener(type, true)) {
1457         return false;
1458     }
1459     IMSA_HILOGD("type: %{public}s.", type.c_str());
1460     if (type == "show" || type == "hide") {
1461         if (panelStatusListener_ == nullptr) {
1462             IMSA_HILOGD("panelStatusListener_ is nullptr, need to be set");
1463             panelStatusListener_ = std::move(statusListener);
1464         }
1465         if (window_ != nullptr) {
1466             if (type == "show" && IsShowing()) {
1467                 panelStatusListener_->OnPanelStatus(windowId_, true);
1468             }
1469             if (type == "hide" && IsHidden()) {
1470                 panelStatusListener_->OnPanelStatus(windowId_, false);
1471             }
1472         }
1473     }
1474     if (type == "sizeChange" || type == "sizeUpdate") {
1475         return SetPanelSizeChangeListener(statusListener);
1476     }
1477     return true;
1478 }
1479 
SetPanelSizeChangeListener(std::shared_ptr<PanelStatusListener> statusListener)1480 bool InputMethodPanel::SetPanelSizeChangeListener(std::shared_ptr<PanelStatusListener> statusListener)
1481 {
1482     if (panelType_ != PanelType::SOFT_KEYBOARD ||
1483         (panelFlag_ != PanelFlag::FLG_FIXED && panelFlag_ != PanelFlag::FLG_FLOATING)) {
1484         return true;
1485     }
1486     if (panelStatusListener_ == nullptr && statusListener != nullptr) {
1487         panelStatusListener_ = std::move(statusListener);
1488     }
1489     std::lock_guard<std::mutex> lock(windowListenerLock_);
1490     if (windowChangedListener_ != nullptr) {
1491         IMSA_HILOGD("windowChangedListener already registered.");
1492         return true;
1493     }
1494     windowChangedListener_ = new (std::nothrow)
1495         WindowChangeListenerImpl([this](WindowSize windowSize) { SizeChange(windowSize); });
1496     if (windowChangedListener_ == nullptr || window_ == nullptr) {
1497         IMSA_HILOGE("observer or window_ is nullptr!");
1498         return false;
1499     }
1500     auto ret = window_->RegisterWindowChangeListener(windowChangedListener_);
1501     if (ret != WMError::WM_OK) {
1502         IMSA_HILOGE("RegisterWindowChangeListener error: %{public}d!", ret);
1503         return false;
1504     }
1505     return true;
1506 }
1507 
ClearPanelListener(const std::string & type)1508 void InputMethodPanel::ClearPanelListener(const std::string &type)
1509 {
1510     if (!MarkListener(type, false)) {
1511         return;
1512     }
1513     IMSA_HILOGD("type: %{public}s.", type.c_str());
1514     if (!sizeChangeRegistered_ && !sizeUpdateRegistered_ && windowChangedListener_ != nullptr && window_ != nullptr) {
1515         auto ret = window_->UnregisterWindowChangeListener(windowChangedListener_);
1516         IMSA_HILOGI("UnregisterWindowChangeListener ret: %{public}d.", ret);
1517         windowChangedListener_ = nullptr;
1518     }
1519     if (panelStatusListener_ == nullptr) {
1520         IMSA_HILOGD("panelStatusListener_ not set, don't need to remove.");
1521         return;
1522     }
1523     if (showRegistered_ || hideRegistered_ || sizeChangeRegistered_ || sizeUpdateRegistered_) {
1524         return;
1525     }
1526     panelStatusListener_ = nullptr;
1527 }
1528 
GetPanelListener()1529 std::shared_ptr<PanelStatusListener> InputMethodPanel::GetPanelListener()
1530 {
1531     return panelStatusListener_;
1532 }
1533 
MarkListener(const std::string & type,bool isRegister)1534 bool InputMethodPanel::MarkListener(const std::string &type, bool isRegister)
1535 {
1536     if (type == "show") {
1537         showRegistered_ = isRegister;
1538     } else if (type == "hide") {
1539         hideRegistered_ = isRegister;
1540     } else if (type == "sizeChange") {
1541         sizeChangeRegistered_ = isRegister;
1542     } else if (type == "sizeUpdate") {
1543         sizeUpdateRegistered_ = isRegister;
1544     } else {
1545         IMSA_HILOGE("type error!");
1546         return false;
1547     }
1548     return true;
1549 }
1550 
GenerateSequenceId()1551 uint32_t InputMethodPanel::GenerateSequenceId()
1552 {
1553     uint32_t seqId = ++sequenceId_;
1554     if (seqId == std::numeric_limits<uint32_t>::max()) {
1555         return ++sequenceId_;
1556     }
1557     return seqId;
1558 }
1559 
IsSizeValid(uint32_t width,uint32_t height)1560 bool InputMethodPanel::IsSizeValid(uint32_t width, uint32_t height)
1561 {
1562     if (width > INT32_MAX || height > INT32_MAX) {
1563         IMSA_HILOGE("width or height over maximum!");
1564         return false;
1565     }
1566     auto defaultDisplay = GetCurDisplay();
1567     if (defaultDisplay == nullptr) {
1568         IMSA_HILOGE("GetDefaultDisplay failed!");
1569         return false;
1570     }
1571     float ratio = panelType_ == PanelType::SOFT_KEYBOARD && panelFlag_ == PanelFlag::FLG_FIXED ?
1572         FIXED_SOFT_KEYBOARD_PANEL_RATIO :
1573         NON_FIXED_SOFT_KEYBOARD_PANEL_RATIO;
1574     auto defaultDisplayHeight = defaultDisplay->GetHeight();
1575     auto defaultDisplayWidth = defaultDisplay->GetWidth();
1576     if (static_cast<float>(height) > defaultDisplayHeight * ratio ||
1577         static_cast<int32_t>(width) > defaultDisplayWidth) {
1578         IMSA_HILOGE("param is invalid, defaultDisplay height: %{public}d, defaultDisplay width %{public}d, target "
1579                     "height: %{public}u, target width: %{public}u!",
1580             defaultDisplayHeight, defaultDisplayWidth, height, width);
1581         return false;
1582     }
1583     return true;
1584 }
1585 
GetKeyboardSize()1586 WindowSize InputMethodPanel::GetKeyboardSize()
1587 {
1588     std::lock_guard<std::mutex> lock(keyboardSizeLock_);
1589     return keyboardSize_;
1590 }
1591 
SizeChange(const WindowSize & size)1592 int32_t InputMethodPanel::SizeChange(const WindowSize &size)
1593 {
1594     IMSA_HILOGD("InputMethodPanel start.");
1595     IMSA_HILOGI("type/flag: %{public}d/%{public}d, width/height: %{public}d/%{public}d.",
1596         static_cast<int32_t>(panelType_), static_cast<int32_t>(panelFlag_), static_cast<int32_t>(size.width),
1597         static_cast<int32_t>(size.height));
1598     {
1599         std::lock_guard<std::mutex> lock(keyboardSizeLock_);
1600         keyboardSize_ = size;
1601     }
1602     auto listener = GetPanelListener();
1603     if (listener == nullptr) {
1604         IMSA_HILOGD("panelStatusListener_ is nullptr");
1605         return ErrorCode::ERROR_NULL_POINTER;
1606     }
1607     PanelAdjustInfo keyboardArea;
1608     if (isInEnhancedAdjust_.load() && GetKeyboardArea(panelFlag_, size, keyboardArea) != ErrorCode::NO_ERROR) {
1609         IMSA_HILOGE("failed to GetKeyboardArea");
1610         return ErrorCode::ERROR_BAD_PARAMETERS;
1611     }
1612     if (sizeChangeRegistered_) {
1613         listener->OnSizeChange(windowId_, keyboardSize_, keyboardArea, "sizeChange");
1614     }
1615     if (sizeUpdateRegistered_) {
1616         listener->OnSizeChange(windowId_, keyboardSize_, keyboardArea, "sizeUpdate");
1617     }
1618     return ErrorCode::NO_ERROR;
1619 }
1620 
GetKeyboardArea(PanelFlag panelFlag,const WindowSize & size,PanelAdjustInfo & keyboardArea)1621 int32_t InputMethodPanel::GetKeyboardArea(PanelFlag panelFlag, const WindowSize &size, PanelAdjustInfo &keyboardArea)
1622 {
1623     bool isPortrait = false;
1624     if (GetWindowOrientation(panelFlag, size.width, isPortrait) != ErrorCode::NO_ERROR) {
1625         IMSA_HILOGE("failed to GetWindowOrientation");
1626         return ErrorCode::ERROR_WINDOW_MANAGER;
1627     }
1628     FullPanelAdjustInfo adjustInfo;
1629     if (GetAdjustInfo(panelFlag, adjustInfo) != ErrorCode::NO_ERROR) {
1630         IMSA_HILOGE("GetAdjustInfo failed");
1631         return ErrorCode::ERROR_BAD_PARAMETERS;
1632     }
1633     if (isPortrait) {
1634         keyboardArea = adjustInfo.portrait;
1635         keyboardArea.top = GetEnhancedLayoutParams().portrait.avoidY;
1636     } else {
1637         keyboardArea = adjustInfo.landscape;
1638         keyboardArea.top = GetEnhancedLayoutParams().landscape.avoidY;
1639     }
1640     return ErrorCode::NO_ERROR;
1641 }
1642 
GetWindowOrientation(PanelFlag panelFlag,uint32_t windowWidth,bool & isPortrait)1643 int32_t InputMethodPanel::GetWindowOrientation(PanelFlag panelFlag, uint32_t windowWidth, bool &isPortrait)
1644 {
1645     if (panelFlag != PanelFlag::FLG_FIXED) {
1646         isPortrait = IsDisplayPortrait();
1647         return ErrorCode::NO_ERROR;
1648     }
1649     DisplaySize displaySize;
1650     if (GetDisplaySize(displaySize) != ErrorCode::NO_ERROR) {
1651         IMSA_HILOGE("failed to GetDisplaySize");
1652         return ErrorCode::ERROR_WINDOW_MANAGER;
1653     }
1654     if (displaySize.portrait.width == displaySize.portrait.height) {
1655         isPortrait = IsDisplayPortrait();
1656         return ErrorCode::NO_ERROR;
1657     }
1658     if (windowWidth == displaySize.portrait.width) {
1659         isPortrait = true;
1660     }
1661     if (windowWidth == displaySize.landscape.width) {
1662         isPortrait = false;
1663     }
1664     return ErrorCode::NO_ERROR;
1665 }
1666 
RegisterKeyboardPanelInfoChangeListener()1667 void InputMethodPanel::RegisterKeyboardPanelInfoChangeListener()
1668 {
1669     kbPanelInfoListener_ =
1670         new (std::nothrow) KeyboardPanelInfoChangeListener([this](const KeyboardPanelInfo &keyboardPanelInfo) {
1671             OnPanelHeightChange(keyboardPanelInfo);
1672             HandleKbPanelInfoChange(keyboardPanelInfo);
1673         });
1674     if (kbPanelInfoListener_ == nullptr) {
1675         return;
1676     }
1677     if (window_ == nullptr) {
1678         return;
1679     }
1680     auto ret = window_->RegisterKeyboardPanelInfoChangeListener(kbPanelInfoListener_);
1681     IMSA_HILOGD("ret: %{public}d.", ret);
1682 }
1683 
OnPanelHeightChange(const Rosen::KeyboardPanelInfo & keyboardPanelInfo)1684 void InputMethodPanel::OnPanelHeightChange(const Rosen::KeyboardPanelInfo &keyboardPanelInfo)
1685 {
1686     auto heightChangeHandler = GetPanelHeightCallback();
1687     if (heightChangeHandler == nullptr) {
1688         return;
1689     }
1690     if (!isInEnhancedAdjust_.load()) {
1691         heightChangeHandler(keyboardPanelInfo.rect_.height_, panelFlag_);
1692         return;
1693     }
1694     bool isPortrait = false;
1695     if (GetWindowOrientation(panelFlag_, keyboardPanelInfo.rect_.width_, isPortrait) != ErrorCode::NO_ERROR) {
1696         IMSA_HILOGE("failed to GetWindowOrientation");
1697         return;
1698     }
1699     if (isPortrait) {
1700         heightChangeHandler(GetEnhancedLayoutParams().portrait.avoidHeight, panelFlag_);
1701     } else {
1702         heightChangeHandler(GetEnhancedLayoutParams().landscape.avoidHeight, panelFlag_);
1703     }
1704 }
1705 
UnregisterKeyboardPanelInfoChangeListener()1706 void InputMethodPanel::UnregisterKeyboardPanelInfoChangeListener()
1707 {
1708     if (window_ == nullptr) {
1709         return;
1710     }
1711     auto ret = window_->UnregisterKeyboardPanelInfoChangeListener(kbPanelInfoListener_);
1712     kbPanelInfoListener_ = nullptr;
1713     IMSA_HILOGD("ret: %{public}d.", ret);
1714 }
1715 
HandleKbPanelInfoChange(const KeyboardPanelInfo & keyboardPanelInfo)1716 void InputMethodPanel::HandleKbPanelInfoChange(const KeyboardPanelInfo &keyboardPanelInfo)
1717 {
1718     IMSA_HILOGD("start.");
1719     InputWindowStatus status = InputWindowStatus::HIDE;
1720     if (keyboardPanelInfo.isShowing_) {
1721         status = InputWindowStatus::SHOW;
1722     }
1723     PanelStatusChangeToImc(status, keyboardPanelInfo.rect_);
1724 }
1725 
IsDisplayPortrait()1726 bool InputMethodPanel::IsDisplayPortrait()
1727 {
1728     auto defaultDisplay = GetCurDisplay();
1729     if (defaultDisplay == nullptr) {
1730         IMSA_HILOGE("GetDefaultDisplay failed!");
1731         return false;
1732     }
1733     auto width = defaultDisplay->GetWidth();
1734     auto height = defaultDisplay->GetHeight();
1735     if (width != height) {
1736         return width < height;
1737     }
1738     auto displayInfo = defaultDisplay->GetDisplayInfo();
1739     if (displayInfo == nullptr) {
1740         IMSA_HILOGE("GetDisplayInfo failed");
1741         return false;
1742     }
1743     auto orientation = displayInfo->GetDisplayOrientation();
1744     IMSA_HILOGI("width equals to height, orientation: %{public}u", static_cast<uint32_t>(orientation));
1745     return orientation == DisplayOrientation::PORTRAIT || orientation == DisplayOrientation::PORTRAIT_INVERTED;
1746 }
1747 
IsDisplayUnfolded()1748 bool InputMethodPanel::IsDisplayUnfolded()
1749 {
1750     return Rosen::DisplayManager::GetInstance().IsFoldable() &&
1751            Rosen::DisplayManager::GetInstance().GetFoldStatus() != Rosen::FoldStatus::FOLDED;
1752 }
1753 
IsSizeValid(PanelFlag panelFlag,uint32_t width,uint32_t height,int32_t displayWidth,int32_t displayHeight)1754 bool InputMethodPanel::IsSizeValid(
1755     PanelFlag panelFlag, uint32_t width, uint32_t height, int32_t displayWidth, int32_t displayHeight)
1756 {
1757     if (width > INT32_MAX || height > INT32_MAX) {
1758         IMSA_HILOGE("width or height over maximum!");
1759         return false;
1760     }
1761     float ratio = panelType_ == PanelType::SOFT_KEYBOARD && panelFlag == PanelFlag::FLG_FIXED ?
1762         FIXED_SOFT_KEYBOARD_PANEL_RATIO :
1763         NON_FIXED_SOFT_KEYBOARD_PANEL_RATIO;
1764     if (static_cast<float>(height) > displayHeight * ratio || static_cast<int32_t>(width) > displayWidth) {
1765         IMSA_HILOGE("param is invalid, defaultDisplay height: %{public}d, defaultDisplay width %{public}d, target "
1766                     "height: %{public}u, target width: %{public}u!",
1767             displayHeight, displayWidth, height, width);
1768         return false;
1769     }
1770     return true;
1771 }
1772 
SetPanelHeightCallback(CallbackFunc heightCallback)1773 void InputMethodPanel::SetPanelHeightCallback(CallbackFunc heightCallback)
1774 {
1775     std::lock_guard<std::mutex> lock(heightCallbackMutex_);
1776     panelHeightCallback_ = std::move(heightCallback);
1777 }
1778 
GetPanelHeightCallback()1779 InputMethodPanel::CallbackFunc InputMethodPanel::GetPanelHeightCallback()
1780 {
1781     std::lock_guard<std::mutex> lock(heightCallbackMutex_);
1782     return panelHeightCallback_;
1783 }
1784 
GetDensityDpi(float & densityDpi)1785 int32_t InputMethodPanel::GetDensityDpi(float &densityDpi)
1786 {
1787     auto defaultDisplay = GetCurDisplay();
1788     if (defaultDisplay == nullptr) {
1789         IMSA_HILOGE("GetDefaultDisplay failed!");
1790         return ErrorCode::ERROR_WINDOW_MANAGER;
1791     }
1792     auto displayInfo = defaultDisplay->GetDisplayInfo();
1793     if (displayInfo == nullptr) {
1794         IMSA_HILOGE("GetDisplayInfo failed!");
1795         return ErrorCode::ERROR_WINDOW_MANAGER;
1796     }
1797     densityDpi = displayInfo->GetDensityInCurResolution();
1798     IMSA_HILOGI("densityDpi: %{public}f", densityDpi);
1799     if (densityDpi <= 0) {
1800         return ErrorCode::ERROR_WINDOW_MANAGER;
1801     }
1802     return ErrorCode::NO_ERROR;
1803 }
1804 
GetDisplaySize(DisplaySize & size)1805 int32_t InputMethodPanel::GetDisplaySize(DisplaySize &size)
1806 {
1807     auto defaultDisplay = GetCurDisplay();
1808     if (defaultDisplay == nullptr) {
1809         IMSA_HILOGE("GetDefaultDisplay failed!");
1810         return ErrorCode::ERROR_WINDOW_MANAGER;
1811     }
1812     auto width = defaultDisplay->GetWidth();
1813     auto height = defaultDisplay->GetHeight();
1814     if (width < height) {
1815         size.portrait = { .width = width, .height = height };
1816         size.landscape = { .width = height, .height = width };
1817     } else {
1818         size.portrait = { .width = height, .height = width };
1819         size.landscape = { .width = width, .height = height };
1820     }
1821     return ErrorCode::NO_ERROR;
1822 }
1823 
SetImmersiveEffectToNone()1824 void InputMethodPanel::SetImmersiveEffectToNone()
1825 {
1826     auto currentEffect = LoadImmersiveEffect();
1827     if (currentEffect.gradientHeight == 0) {
1828         currentEffect.gradientMode = GradientMode::NONE;
1829         currentEffect.fluidLightMode = FluidLightMode::NONE;
1830         StoreImmersiveEffect(currentEffect);
1831         return;
1832     }
1833 
1834     // The SetImmersiveEffect API must be called after the AdjustPanelRect API is called.
1835     auto layoutParams = GetKeyboardLayoutParams();
1836     Rosen::KeyboardLayoutParams emptyParams;
1837     if (layoutParams == emptyParams) {
1838         IMSA_HILOGW("set gradientHeight to zero");
1839         return;
1840     }
1841 
1842     currentEffect.gradientHeight = 0;
1843     currentEffect.gradientMode = GradientMode::NONE;
1844     currentEffect.fluidLightMode = FluidLightMode::NONE;
1845     auto ret = AdjustLayout(layoutParams, currentEffect);
1846     if (ret != ErrorCode::NO_ERROR) {
1847         IMSA_HILOGE("adjust failed, ret: %{public}d", ret);
1848         return;
1849     }
1850     StoreImmersiveEffect(currentEffect);
1851     UpdateImmersiveHotArea();
1852     IMSA_HILOGW("set gradientHeight to zero and adjust layout success");
1853 }
1854 
SetImmersiveMode(ImmersiveMode mode)1855 int32_t InputMethodPanel::SetImmersiveMode(ImmersiveMode mode)
1856 {
1857     if ((mode != ImmersiveMode::NONE_IMMERSIVE && mode != ImmersiveMode::LIGHT_IMMERSIVE &&
1858         mode != ImmersiveMode::DARK_IMMERSIVE)) {
1859         IMSA_HILOGE("invalid mode: %{public}d", mode);
1860         return ErrorCode::ERROR_PARAMETER_CHECK_FAILED;
1861     }
1862 
1863     auto currentMode = GetImmersiveMode();
1864     if (!IsShowing()) {
1865         if (mode != currentMode && mode == ImmersiveMode::NONE_IMMERSIVE) {
1866             SetImmersiveEffectToNone();
1867         }
1868         StoreImmersiveMode(mode);
1869         IMSA_HILOGD("window is not show, mode: %{public}d", mode);
1870         return ErrorCode::NO_ERROR;
1871     }
1872 
1873     if (window_ == nullptr) {
1874         IMSA_HILOGE("window is null");
1875         return ErrorCode::ERROR_IME;
1876     }
1877 
1878     if (mode != currentMode && mode == ImmersiveMode::NONE_IMMERSIVE) {
1879         SetImmersiveEffectToNone();
1880     }
1881     KeyboardEffectOption option = ConvertToWmEffect(mode, LoadImmersiveEffect());
1882     // call window manager to set immersive mode
1883     auto ret = window_->ChangeKeyboardEffectOption(option);
1884     if (ret == WMError::WM_DO_NOTHING) {
1885         IMSA_HILOGW("repeat set mode new:%{public}d, old:%{public}d", mode, currentMode);
1886         return ErrorCode::NO_ERROR;
1887     }
1888     if (ret != WMError::WM_OK) {
1889         IMSA_HILOGE("ChangeKeyboardEffectOption failed, ret: %{public}d", ret);
1890         return ErrorCode::ERROR_WINDOW_MANAGER;
1891     }
1892     StoreImmersiveMode(mode);
1893     IMSA_HILOGI("SetImmersiveMode success, mode: %{public}d", mode);
1894     return ErrorCode::NO_ERROR;
1895 }
1896 
IsValidGradientHeight(uint32_t gradientHeight)1897 bool InputMethodPanel::IsValidGradientHeight(uint32_t gradientHeight)
1898 {
1899     if (gradientHeight > INT32_MAX) {
1900         IMSA_HILOGE("gradientHeight over maximum!");
1901         return false;
1902     }
1903     DisplaySize displaySize;
1904     auto ret = GetDisplaySize(displaySize);
1905     if (ret != ErrorCode::NO_ERROR) {
1906         IMSA_HILOGE("Get portrait display size failed, ret: %{public}d", ret);
1907         return false;
1908     }
1909 
1910     if (static_cast<float>(gradientHeight) > displaySize.portrait.height * GRADIENT_HEIGHT_RATIO) {
1911         IMSA_HILOGE("invalid gradientHeight:%{public}u, portraitHeight:%{public}u", gradientHeight,
1912             displaySize.portrait.height);
1913         return false;
1914     }
1915 
1916     if (static_cast<float>(gradientHeight) > displaySize.landscape.height * GRADIENT_HEIGHT_RATIO) {
1917         IMSA_HILOGE("invalid gradientHeight:%{public}u, landscapeHeight:%{public}u", gradientHeight,
1918             displaySize.landscape.height);
1919         return false;
1920     }
1921 
1922     return true;
1923 }
1924 
IsValidParam(const ImmersiveEffect & effect,const KeyboardLayoutParams & layoutParams)1925 int32_t InputMethodPanel::IsValidParam(const ImmersiveEffect &effect, const KeyboardLayoutParams &layoutParams)
1926 {
1927     if (effect.gradientMode < GradientMode::NONE || effect.gradientMode >= GradientMode::END ||
1928         effect.fluidLightMode < FluidLightMode::NONE || effect.fluidLightMode >= FluidLightMode::END) {
1929         IMSA_HILOGE("invalid effect, gradientMpde:%{public}d, fluidLightMode:%{public}d", effect.gradientMode,
1930             effect.fluidLightMode);
1931         return ErrorCode::ERROR_PARAMETER_CHECK_FAILED;
1932     }
1933 
1934     // The gradient mode and the fluid light mode can only be used when the immersive mode is enabled.
1935     if (GetImmersiveMode() == ImmersiveMode::NONE_IMMERSIVE) {
1936         if (effect.gradientMode != GradientMode::NONE || effect.fluidLightMode != FluidLightMode::NONE ||
1937             effect.gradientHeight != 0) {
1938             IMSA_HILOGE("immersiveMode is NONE, but gradientMode=%{public}d, fluidLightMode=%{public}d",
1939                 effect.gradientMode, effect.fluidLightMode);
1940             return ErrorCode::ERROR_IMA_INVALID_IMMERSIVE_EFFECT;
1941         }
1942         return ErrorCode::NO_ERROR;
1943     }
1944 
1945     // The fluid light mode can only be used when the gradient mode is enabled.
1946     if (effect.gradientMode == GradientMode::NONE && effect.fluidLightMode != FluidLightMode::NONE) {
1947         IMSA_HILOGE("gradientMode is NONE, but fluidLightMode=%{public}d", effect.fluidLightMode);
1948         return ErrorCode::ERROR_IMA_INVALID_IMMERSIVE_EFFECT;
1949     }
1950 
1951     if (effect.gradientMode == GradientMode::NONE && effect.gradientHeight != 0) {
1952         IMSA_HILOGE("gradientMode is NONE, but gradientHeight:%{public}u", effect.gradientHeight);
1953         return ErrorCode::ERROR_IMA_INVALID_IMMERSIVE_EFFECT;
1954     }
1955 
1956     // Only system applications can set the fluid light mode.
1957     if (!InputMethodAbility::GetInstance().IsSystemApp() && effect.fluidLightMode != FluidLightMode::NONE) {
1958         IMSA_HILOGE("only system app can set fluidLightMode:%{public}d", effect.fluidLightMode);
1959         return ErrorCode::ERROR_STATUS_SYSTEM_PERMISSION;
1960     }
1961 
1962     // The gradient height cannot be greater than the screen height * GRADIENT_HEIGHT_RATIO.
1963     if (!IsValidGradientHeight(effect.gradientHeight)) {
1964         return ErrorCode::ERROR_PARAMETER_CHECK_FAILED;
1965     }
1966 
1967     // The SetImmersiveEffect API must be called after the AdjustPanelRect API is called.
1968     Rosen::KeyboardLayoutParams emptyParams;
1969     if (layoutParams == emptyParams) {
1970         IMSA_HILOGE("adjust is not call, %{public}s", effect.ToString().c_str());
1971         return ErrorCode::ERROR_IMA_PRECONDITION_REQUIRED;
1972     }
1973     return ErrorCode::NO_ERROR;
1974 }
1975 
IsImmersiveEffectSupported()1976 bool InputMethodPanel::IsImmersiveEffectSupported()
1977 {
1978     static int32_t isSupport = 0;
1979     static std::mutex isSupportMutex;
1980     if (isSupport != 0) {
1981         return isSupport == 1 ? true : false;
1982     }
1983 
1984     std::lock_guard<std::mutex> lock(isSupportMutex);
1985     bool isSupportTemp = false;
1986     int32_t ret = InputMethodAbility::GetInstance().IsCapacitySupport(
1987         static_cast<int32_t>(CapacityType::IMMERSIVE_EFFECT), isSupportTemp);
1988     if (ret != ErrorCode::NO_ERROR) {
1989         IMSA_HILOGE("IsCapacitySupport failed, ret:%{public}d", ret);
1990         return false;
1991     }
1992 
1993     if (isSupportTemp) {
1994         isSupport = 1;
1995     } else {
1996         isSupport = -1;
1997     }
1998     IMSA_HILOGI("isSupportTemp:%{public}d", isSupportTemp);
1999     return isSupportTemp;
2000 }
2001 
ConvertToWmEffect(ImmersiveMode mode,const ImmersiveEffect & effect)2002 KeyboardEffectOption InputMethodPanel::ConvertToWmEffect(ImmersiveMode mode, const ImmersiveEffect &effect)
2003 {
2004     KeyboardEffectOption option;
2005     option.blurHeight_ = effect.gradientHeight;
2006     option.viewMode_ = static_cast<KeyboardViewMode>(mode);
2007     option.gradientMode_ = static_cast<KeyboardGradientMode>(effect.gradientMode);
2008     option.flowLightMode_ = static_cast<KeyboardFlowLightMode>(effect.fluidLightMode);
2009     IMSA_HILOGI("effect: %{public}s", effect.ToString().c_str());
2010     return option;
2011 }
2012 
UpdateImmersiveHotArea()2013 void InputMethodPanel::UpdateImmersiveHotArea()
2014 {
2015     auto hotAreas = GetHotAreas();
2016     if (!hotAreas.isSet) {
2017         return;
2018     }
2019     FullPanelAdjustInfo adjustInfo;
2020     auto ret = GetAdjustInfo(panelFlag_, adjustInfo);
2021     if (ret != ErrorCode::NO_ERROR) {
2022         IMSA_HILOGE("GetAdjustInfo failed ret: %{public}d", ret);
2023         return;
2024     }
2025 
2026     CalculateHotAreas(GetEnhancedLayoutParams(), GetKeyboardLayoutParams(), adjustInfo, hotAreas);
2027     auto wmsHotAreas = ConvertToWMSHotArea(hotAreas);
2028     WMError result = window_->SetKeyboardTouchHotAreas(wmsHotAreas);
2029     if (result != WMError::WM_OK) {
2030         IMSA_HILOGE("SetKeyboardTouchHotAreas error, err: %{public}d!", result);
2031         return;
2032     }
2033     SetHotAreas(hotAreas);
2034     IMSA_HILOGI("success, portrait: %{public}s", HotArea::ToString(hotAreas.portrait.keyboardHotArea).c_str());
2035     IMSA_HILOGI("success, landscape: %{public}s", HotArea::ToString(hotAreas.landscape.keyboardHotArea).c_str());
2036 }
2037 
SetImmersiveEffect(const ImmersiveEffect & effect)2038 int32_t InputMethodPanel::SetImmersiveEffect(const ImmersiveEffect &effect)
2039 {
2040     if (!IsImmersiveEffectSupported()) {
2041         IMSA_HILOGE("immersive effect is not supported");
2042         return ErrorCode::ERROR_DEVICE_UNSUPPORTED;
2043     }
2044     auto layoutParams = GetKeyboardLayoutParams();
2045     auto ret = IsValidParam(effect, layoutParams);
2046     if (ret != ErrorCode::NO_ERROR) {
2047         IMSA_HILOGE("invalid param, ret:%{public}d", ret);
2048         return ret;
2049     }
2050 
2051     // adjust again
2052     auto currentEffect = LoadImmersiveEffect();
2053     ImmersiveEffect targetEffect = effect;
2054     if (currentEffect.gradientMode != effect.gradientMode && effect.gradientMode == GradientMode::NONE) {
2055         targetEffect =
2056             { .gradientHeight = 0, .gradientMode = GradientMode::NONE, .fluidLightMode = FluidLightMode::NONE };
2057     }
2058     ret = AdjustLayout(layoutParams, targetEffect);
2059     if (ret != ErrorCode::NO_ERROR) {
2060         IMSA_HILOGE("AdjustLayout failed, ret:%{public}d", ret);
2061         return ret;
2062     }
2063     UpdateImmersiveHotArea();
2064 
2065     if (!IsShowing()) {
2066         StoreImmersiveEffect(targetEffect);
2067         IMSA_HILOGW("keyboard is not showing, do nothing");
2068         return ErrorCode::NO_ERROR;
2069     }
2070     if (window_ == nullptr) {
2071         IMSA_HILOGE("window_ is nullptr");
2072         return ErrorCode::ERROR_NULL_POINTER;
2073     }
2074     auto mode = GetImmersiveMode();
2075     KeyboardEffectOption option = ConvertToWmEffect(mode, targetEffect);
2076     // call window manager to set immersive mode
2077     auto wmRet = window_->ChangeKeyboardEffectOption(option);
2078     if (wmRet == WMError::WM_DO_NOTHING) {
2079         IMSA_HILOGW("repeat set mode new:, old:%{public}d", mode);
2080         StoreImmersiveEffect(targetEffect);
2081         return ErrorCode::NO_ERROR;
2082     }
2083     if (wmRet != WMError::WM_OK) {
2084         IMSA_HILOGE("ChangeKeyboardViewMode failed, wmRet: %{public}d", wmRet);
2085         return ErrorCode::ERROR_WINDOW_MANAGER;
2086     }
2087     StoreImmersiveEffect(targetEffect);
2088     IMSA_HILOGI("success, %{public}s", effect.ToString().c_str());
2089     return ErrorCode::NO_ERROR;
2090 }
2091 
GetImmersiveMode()2092 ImmersiveMode InputMethodPanel::GetImmersiveMode()
2093 {
2094     std::lock_guard<std::mutex> lock(immersiveModeMutex_);
2095     IMSA_HILOGD("mode: %{public}d", immersiveMode_);
2096     return immersiveMode_;
2097 }
2098 
StoreImmersiveMode(ImmersiveMode mode)2099 void InputMethodPanel::StoreImmersiveMode(ImmersiveMode mode)
2100 {
2101     std::lock_guard<std::mutex> lock(immersiveModeMutex_);
2102     immersiveMode_ = mode;
2103 }
2104 
SetHotAreas(const HotAreas & hotAreas)2105 void InputMethodPanel::SetHotAreas(const HotAreas &hotAreas)
2106 {
2107     std::lock_guard<std::mutex> lock(hotAreasLock_);
2108     hotAreas_ = hotAreas;
2109 }
2110 
GetHotAreas()2111 HotAreas InputMethodPanel::GetHotAreas()
2112 {
2113     std::lock_guard<std::mutex> lock(hotAreasLock_);
2114     return hotAreas_;
2115 }
2116 
GetCurDisplay()2117 sptr<Rosen::Display> InputMethodPanel::GetCurDisplay()
2118 {
2119     IMSA_HILOGD("enter!!");
2120     uint64_t displayId = GetCurDisplayId();
2121     auto displayInfo = Rosen::DisplayManager::GetInstance().GetDisplayById(displayId);
2122     if (displayInfo == nullptr) {
2123         IMSA_HILOGE("get display info err:%{public}" PRIu64 "!", displayId);
2124         displayInfo = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
2125     }
2126     return displayInfo;
2127 }
2128 
GetCurDisplayId()2129 uint64_t InputMethodPanel::GetCurDisplayId()
2130 {
2131     return InputMethodAbility::GetInstance().GetInputAttribute().callingDisplayId;
2132 }
2133 
IsInMainDisplay()2134 bool InputMethodPanel::IsInMainDisplay()
2135 {
2136     IMSA_HILOGD("enter!!");
2137     uint64_t displayId = GetCurDisplayId();
2138     auto primaryDisplay = Rosen::DisplayManager::GetInstance().GetPrimaryDisplaySync();
2139     if (primaryDisplay == nullptr) {
2140         IMSA_HILOGE("primaryDisplay failed!");
2141         return true;
2142     }
2143     return primaryDisplay->GetId() == displayId;
2144 }
2145 
SetIgnoreAdjustInputTypes(const std::vector<int32_t> & inputTypes)2146 void InputMethodPanel::SetIgnoreAdjustInputTypes(const std::vector<int32_t> &inputTypes)
2147 {
2148     std::lock_guard<std::mutex> lock(ignoreAdjustInputTypeLock_);
2149     ignoreAdjustInputTypes_ = inputTypes;
2150 }
2151 
GetIgnoreAdjustInputTypes()2152 std::vector<int32_t> InputMethodPanel::GetIgnoreAdjustInputTypes()
2153 {
2154     std::lock_guard<std::mutex> lock(ignoreAdjustInputTypeLock_);
2155     return ignoreAdjustInputTypes_;
2156 }
2157 
IsNeedConfig()2158 bool InputMethodPanel::IsNeedConfig()
2159 {
2160     bool needConfig = true;
2161     bool isSpecialInputType = false;
2162     auto inputType = InputMethodAbility::GetInstance().GetInputType();
2163     if (!isIgnorePanelAdjustInitialized_.load()) {
2164         IgnoreSysPanelAdjust ignoreSysPanelAdjust;
2165         auto isSuccess = SysCfgParser::ParseIgnoreSysPanelAdjust(ignoreSysPanelAdjust);
2166         if (isSuccess) {
2167             SetIgnoreAdjustInputTypes(ignoreSysPanelAdjust.inputType);
2168         }
2169         isIgnorePanelAdjustInitialized_.store(true);
2170     }
2171     std::vector<int32_t> ignoreAdjustInputTypes = GetIgnoreAdjustInputTypes();
2172     auto it = std::find_if(
2173         ignoreAdjustInputTypes.begin(), ignoreAdjustInputTypes.end(), [inputType](const int32_t &mInputType) {
2174             return static_cast<int32_t>(inputType) == mInputType;
2175         });
2176     isSpecialInputType = (it != ignoreAdjustInputTypes.end());
2177     if (isSpecialInputType || !IsInMainDisplay()) {
2178         needConfig = false;
2179     }
2180     IMSA_HILOGD("isNeedConfig is %{public}d", needConfig);
2181     return needConfig;
2182 }
2183 
SetKeepScreenOn(bool isKeepScreenOn)2184 int32_t InputMethodPanel::SetKeepScreenOn(bool isKeepScreenOn)
2185 {
2186     if (window_ == nullptr) {
2187         IMSA_HILOGE("window_ is nullptr!");
2188         return ErrorCode::ERROR_WINDOW_MANAGER;
2189     }
2190     auto ret = window_->SetKeepScreenOn(isKeepScreenOn);
2191     if (ret != WMError::WM_OK) {
2192         IMSA_HILOGE("SetKeepScreenOn error: %{public}d!", ret);
2193         return ErrorCode::ERROR_WINDOW_MANAGER;
2194     }
2195     IMSA_HILOGI("SetKeepScreenOn success");
2196     return ErrorCode::NO_ERROR;
2197 }
2198 
GetKeyboardLayoutParams()2199 Rosen::KeyboardLayoutParams InputMethodPanel::GetKeyboardLayoutParams()
2200 {
2201     std::lock_guard<std::mutex> lock(keyboardLayoutParamsMutex_);
2202     return keyboardLayoutParams_;
2203 }
2204 
SetKeyboardLayoutParams(Rosen::KeyboardLayoutParams params)2205 void InputMethodPanel::SetKeyboardLayoutParams(Rosen::KeyboardLayoutParams params)
2206 {
2207     std::lock_guard<std::mutex> lock(keyboardLayoutParamsMutex_);
2208     keyboardLayoutParams_ = std::move(params);
2209 }
2210 
GetEnhancedLayoutParams()2211 EnhancedLayoutParams InputMethodPanel::GetEnhancedLayoutParams()
2212 {
2213     std::lock_guard<std::mutex> lock(enhancedLayoutParamMutex_);
2214     return enhancedLayoutParams_;
2215 }
2216 
SetEnhancedLayoutParams(EnhancedLayoutParams params)2217 void InputMethodPanel::SetEnhancedLayoutParams(EnhancedLayoutParams params)
2218 {
2219     std::lock_guard<std::mutex> lock(enhancedLayoutParamMutex_);
2220     enhancedLayoutParams_ = params;
2221 }
2222 
LoadImmersiveEffect()2223 ImmersiveEffect InputMethodPanel::LoadImmersiveEffect()
2224 {
2225     std::lock_guard<std::mutex> lock(immersiveEffectMutex_);
2226     return immersiveEffect_;
2227 }
2228 
StoreImmersiveEffect(ImmersiveEffect effect)2229 void InputMethodPanel::StoreImmersiveEffect(ImmersiveEffect effect)
2230 {
2231     std::lock_guard<std::mutex> lock(immersiveEffectMutex_);
2232     immersiveEffect_ = effect;
2233 }
2234 
GetChangeY()2235 ChangeY InputMethodPanel::GetChangeY()
2236 {
2237     std::lock_guard<std::mutex> lock(changeYMutex_);
2238     return changeY_;
2239 }
2240 
SetChangeY(ChangeY changeY)2241 void InputMethodPanel::SetChangeY(ChangeY changeY)
2242 {
2243     std::lock_guard<std::mutex> lock(changeYMutex_);
2244     changeY_ = changeY;
2245 }
2246 } // namespace MiscServices
2247 } // namespace OHOS