* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef INPUT_METHOD_PANEL_H
#define INPUT_METHOD_PANEL_H
#include <cstdint>
#include <functional>
#include <map>
#include <string>
#include "calling_window_info.h"
#include "display_manager.h"
#include "input_method_utils.h"
#include "input_status_info.h"
#include "input_window_info.h"
#include "native_engine/native_engine.h"
#include "panel_common.h"
#include "panel_info.h"
#include "window_change_listener_impl.h"
#include "wm_common.h"
namespace OHOS {
namespace MiscServices {
constexpr int FOLD_TOP = 0;
constexpr int FOLD_LEFT = 0;
constexpr int FOLD_RIGHT = 0;
constexpr int FOLD_BOTTOM = 606;
constexpr int UNFOLD_TOP = 0;
constexpr int UNFOLD_LEFT = 0;
constexpr int UNFOLD_RIGHT = 0;
constexpr int UNFOLD_BOTTOM = 822;
constexpr int COMMON_BOTTOM = 809;
class InputMethodPanel {
public:
static constexpr uint32_t INVALID_WINDOW_ID = 0;
using CallbackFunc = std::function<void(uint32_t, PanelFlag)>;
InputMethodPanel() = default;
~InputMethodPanel();
int32_t SetUiContent(const std::string &contentInfo, napi_env env, std::shared_ptr<NativeReference> contentStorage);
int32_t SetUiContentAni(const std::string &contentInfo, ani_env* env, ani_object storage);
int32_t CreatePanel(const std::shared_ptr<AbilityRuntime::Context> &context, const PanelInfo &panelInfo);
int32_t DestroyPanel();
int32_t Resize(uint32_t width, uint32_t height);
int32_t MoveTo(int32_t x, int32_t y);
int32_t StartMoving();
int32_t GetDisplayId(uint64_t &displayId);
int32_t AdjustKeyboard();
int32_t AdjustPanelRect(const PanelFlag panelFlag, const LayoutParams &layoutParams, bool needUpdateRegion,
bool needConfig, bool isColdStartRequest);
int32_t AdjustPanelRect(PanelFlag panelFlag, EnhancedLayoutParams params, HotAreas hotAreas,
bool isColdStartRequest);
int32_t UpdateRegion(std::vector<Rosen::Rect> region);
std::tuple<std::vector<std::string>, std::vector<std::string>> GetScreenStatus(const PanelFlag panelFlag);
int32_t ChangePanelFlag(PanelFlag panelFlag);
PanelType GetPanelType();
PanelFlag GetPanelFlag();
int32_t ShowPanel(Trigger trigger, uint32_t windowId = 0);
int32_t HidePanel();
int32_t SizeChange(const WindowSize &size);
WindowSize GetKeyboardSize();
bool SetPanelStatusListener(std::shared_ptr<PanelStatusListener> statusListener, const std::string &type);
void ClearPanelListener(const std::string &type);
int32_t SetCallingWindow(uint32_t windowId);
int32_t GetCallingWindowInfo(CallingWindowInfo &windowInfo);
int32_t SetPrivacyMode(bool isPrivacyMode);
bool IsShowing();
bool IsDisplayPortrait();
int32_t SetTextFieldAvoidInfo(double positionY, double height);
void SetPanelHeightCallback(CallbackFunc heightCallback);
int32_t IsEnhancedParamValid(PanelFlag panelFlag, EnhancedLayoutParams ¶ms);
int32_t SetImmersiveMode(ImmersiveMode mode);
ImmersiveMode GetImmersiveMode();
bool IsInMainDisplay();
int32_t SetImmersiveEffect(const ImmersiveEffect &effect);
ImmersiveEffect LoadImmersiveEffect();
int32_t SetKeepScreenOn(bool isKeepScreenOn);
int32_t SetSystemPanelButtonColor(const std::string &fillColor, const std::string &backgroundColor);
int32_t GetSystemPanelCurrentInsets(uint64_t displayId, SystemPanelInsets &systemPanelInsets);
int32_t SetShadow(const Shadow &shadow);
int32_t CovertSetShadowResult(const Rosen::WMError ret, const SetShadowOperation operation);
bool IsKeyboardBottomElevated(PanelFlag flag);
bool IsFunctionButtonVisible(bool isKeyboardElevated);
uint32_t windowId_ = INVALID_WINDOW_ID;
private:
class KeyboardPanelInfoChangeListener : public Rosen::IKeyboardPanelInfoChangeListener {
public:
using ChangeHandler = std::function<void(const Rosen::KeyboardPanelInfo &keyboardPanelInfo)>;
explicit KeyboardPanelInfoChangeListener(ChangeHandler handler) : handler_(std::move(handler)) { }
~KeyboardPanelInfoChangeListener() = default;
void OnKeyboardPanelInfoChanged(const Rosen::KeyboardPanelInfo &keyboardPanelInfo) override
{
if (handler_ == nullptr) {
return;
}
handler_(keyboardPanelInfo);
}
private:
ChangeHandler handler_ = nullptr;
};
void RegisterKeyboardPanelInfoChangeListener();
void UnregisterKeyboardPanelInfoChangeListener();
void OnKeyboardPanelInfoChange(const Rosen::KeyboardPanelInfo &keyboardPanelInfo);
void OnPanelHeightChange(const Rosen::KeyboardPanelInfo &keyboardPanelInfo);
void HandleKbPanelInfoChange(const Rosen::KeyboardPanelInfo &keyboardPanelInfo);
sptr<Rosen::IKeyboardPanelInfoChangeListener> kbPanelInfoListener_ { nullptr };
private:
class VisibilityChangeListener : public Rosen::IOcclusionStateChangedListener {
public:
using ChangeHandler = std::function<void(Rosen::WindowVisibilityState)>;
explicit VisibilityChangeListener(ChangeHandler handler) : handler_(std::move(handler)) { }
~VisibilityChangeListener() = default;
void OnOcclusionStateChanged(const Rosen::WindowVisibilityState state) override
{
if (handler_ != nullptr) {
handler_(state);
}
}
private:
ChangeHandler handler_ = nullptr;
};
int32_t RegisterVisibilityChangeListener();
int32_t UnregisterVisibilityChangeListener();
void OnVisibilityChange(const Rosen::WindowVisibilityState state);
std::atomic<bool> isVisible_{ false };
sptr<Rosen::IOcclusionStateChangedListener> visibilityChangeListener_{ nullptr };
private:
bool IsHidden();
int32_t SetPanelProperties();
std::string GeneratePanelName();
void PanelStatusChange(const InputWindowStatus &status);
void PanelStatusChangeToImc(
const InputWindowStatus &status, const Rosen::Rect &rect, bool triggeredBySwitchCandidate = false);
bool MarkListener(const std::string &type, bool isRegister);
bool SetPanelSizeChangeListener(std::shared_ptr<PanelStatusListener> statusListener);
std::shared_ptr<PanelStatusListener> GetPanelListener();
static uint32_t GenerateSequenceId();
bool IsSizeValid(uint32_t width, uint32_t height);
bool IsSizeValid(PanelFlag panelFlag, uint32_t width, uint32_t height, int32_t displayWidth, int32_t displayHeight);
bool IsRectValid(const Rosen::Rect &rect, const WindowSize &displaySize);
bool IsRectValid(PanelFlag panelFlag, const Rosen::Rect &rect, const WindowSize &displaySize);
int32_t GetResizeParams(Rosen::Rect &portrait, Rosen::Rect &landscape, uint32_t width, uint32_t height);
int32_t ParseEnhancedParams(
PanelFlag panelFlag, const FullPanelAdjustInfo &adjustInfo, EnhancedLayoutParams ¶ms);
int32_t RectifyRect(bool isFullScreen, EnhancedLayoutParam &layoutParam, const WindowSize &displaySize,
PanelFlag panelFlag, const PanelAdjustInfo &adjustInfo);
int32_t CalculateAvoidHeight(EnhancedLayoutParam &layoutParam, const WindowSize &displaySize, PanelFlag panelFlag,
const PanelAdjustInfo &adjustInfo);
int32_t ParseParams(PanelFlag panelFlag, const LayoutParams &input, Rosen::KeyboardLayoutParams &output,
bool needConfig = true);
void ParseParam(PanelFlag panelFlag, const PanelAdjustInfo &adjustInfo, const WindowSize &displaySize,
const Rosen::Rect &inputRect, EnhancedLayoutParam &outputParam);
void CalculateHotAreas(const EnhancedLayoutParams &enhancedParams, const Rosen::KeyboardLayoutParams ¶ms,
const FullPanelAdjustInfo &adjustInfo, HotAreas &hotAreas);
void CalculateDefaultHotArea(const Rosen::Rect &keyboard, const Rosen::Rect &panel,
const PanelAdjustInfo &adjustInfo, HotArea &hotArea, uint32_t changeY);
void CalculateHotArea(const Rosen::Rect &keyboard, const Rosen::Rect &panel, const PanelAdjustInfo &adjustInfo,
HotArea &hotArea, uint32_t changeY);
void CalculateEnhancedHotArea(
const EnhancedLayoutParam &layout, const PanelAdjustInfo &adjustInfo, HotArea &hotArea, uint32_t changeY);
void RectifyAreas(const std::vector<Rosen::Rect> &availableAreas, std::vector<Rosen::Rect> &areas);
Rosen::Rect GetRectIntersection(Rosen::Rect a, Rosen::Rect b);
uint32_t SafeSubtract(uint32_t minuend, uint32_t subtrahend);
int32_t ResizePanel(uint32_t width, uint32_t height);
int32_t ResizeWithoutAdjust(uint32_t width, uint32_t height);
int32_t ResizeEnhancedPanel(uint32_t width, uint32_t height);
void UpdateRectParams(
Rosen::Rect &portrait, Rosen::Rect &landscape, uint32_t width, uint32_t height, const LayoutParams &currParams);
void RectifyResizeParams(LayoutParams ¶ms, const DisplaySize &displaySize);
int32_t MovePanelRect(int32_t x, int32_t y);
int32_t MoveEnhancedPanelRect(int32_t x, int32_t y);
bool IsDisplayUnfolded();
int32_t GetDisplaySize(DisplaySize &size);
int32_t GetDensityDpi(float &densityDpi);
int32_t InitAdjustInfo();
int32_t GetAdjustInfo(PanelFlag panelFlag, FullPanelAdjustInfo &fullPanelAdjustInfo);
void UpdateResizeParams();
void UpdateHotAreas();
void UpdateLayoutInfo(PanelFlag panelFlag, const LayoutParams ¶ms, const EnhancedLayoutParams &enhancedParams,
const Rosen::KeyboardLayoutParams &wmsParams, bool isEnhanced);
Rosen::KeyboardLayoutParams ConvertToWMSParam(PanelFlag panelFlag, const EnhancedLayoutParams &layoutParams);
Rosen::KeyboardTouchHotAreas ConvertToWMSHotArea(const HotAreas &hotAreas);
int32_t GetKeyboardArea(PanelFlag panelFlag, const WindowSize &size, PanelAdjustInfo &keyboardArea);
int32_t GetWindowOrientation(PanelFlag panelFlag, uint32_t windowWidth, bool &isPortrait);
int32_t GetInputWindowAvoidArea(PanelFlag panelFlag, Rosen::Rect &windowRect);
sptr<Rosen::Display> GetCurDisplay();
uint64_t GetCurDisplayId();
bool IsNeedConfig(bool ignoreIsMainDisplay = false);
int32_t IsValidParam(const ImmersiveEffect &effect, const Rosen::KeyboardLayoutParams &layoutParams);
int32_t AdjustLayout(const Rosen::KeyboardLayoutParams ¶m, bool isColdStartRequest);
int32_t AdjustLayout(const Rosen::KeyboardLayoutParams ¶m, const ImmersiveEffect &effect,
bool isColdStartRequest);
int32_t ExecuteAdjustLayout(const Rosen::KeyboardLayoutParams ¶m);
int32_t AdjustLayoutWithoutScb(const Rosen::KeyboardLayoutParams ¶m);
int32_t FullScreenPrepare(Rosen::KeyboardLayoutParams ¶m, const ImmersiveEffect &effect);
int32_t NormalImePrepare(Rosen::KeyboardLayoutParams ¶m, const ImmersiveEffect &effect);
int32_t PrepareAdjustLayout(Rosen::KeyboardLayoutParams ¶m, const ImmersiveEffect &effect);
bool IsImmersiveEffectSupported();
Rosen::KeyboardEffectOption ConvertToWmEffect(ImmersiveMode mode, const ImmersiveEffect &effect);
void SetImmersiveEffectToNone();
void UpdateImmersiveHotArea();
bool IsValidGradientHeight(uint32_t gradientHeight);
int32_t HandleImmersiveEffectWhenShowing(const ImmersiveEffect &targetEffect);
Rosen::KeyboardLayoutParams GetKeyboardLayoutParams();
void SetKeyboardLayoutParams(Rosen::KeyboardLayoutParams params);
EnhancedLayoutParams GetEnhancedLayoutParams();
void SetEnhancedLayoutParams(EnhancedLayoutParams params);
std::vector<int32_t> GetIgnoreAdjustInputTypes();
void SetIgnoreAdjustInputTypes(const std::vector<int32_t> &inputTypes);
void StoreImmersiveEffect(ImmersiveEffect effect);
HotAreas GetHotAreas();
void SetHotAreas(const HotAreas &hotAreas);
ChangeY GetChangeY();
void SetChangeY(ChangeY changeY);
void StoreImmersiveMode(ImmersiveMode mode);
CallbackFunc GetPanelHeightCallback();
bool IsVectorsEqual(const std::vector<std::string>& vec1, const std::vector<std::string>& vec2);
int32_t AreaInsets(SystemPanelInsets &systemPanelInsets, sptr<Rosen::Display> displayPtr);
int32_t SetWindowShadow(const Shadow &shadow);
bool IsKeyboardRectAtBottom();
bool IsNeedNotify(PanelFlag panelFlag);
void WaitSetUIContent();
int32_t ShowKeyboardToWms(uint32_t windowId);
void UpdatePanelFlag(PanelFlag newPanelFlag);
void NotifySoftKeyBoardInfoChanged(PanelFlag panelFlag, InputWindowStatus status);
int32_t SetHotAreasOnAdjust(HotAreas hotAreas);
int32_t UpdatePanelFLagToWindow(PanelFlag panelFlag);
bool NeedAdjustPanelRect();
void AddAdjustPanelRect();
sptr<OHOS::Rosen::Window> window_ = nullptr;
sptr<OHOS::Rosen::WindowOption> winOption_ = nullptr;
PanelType panelType_ = PanelType::SOFT_KEYBOARD;
PanelFlag panelFlag_ = PanelFlag::FLG_FIXED;
bool showRegistered_ = false;
bool hideRegistered_ = false;
bool sizeChangeRegistered_ = false;
bool sizeUpdateRegistered_ = false;
uint32_t invalidGravityPercent = 0;
uint32_t callingWindowId_ = 0;
std::shared_ptr<PanelStatusListener> panelStatusListener_ = nullptr;
static std::atomic<uint32_t> sequenceId_;
bool isScbEnable_ { false };
std::mutex panelAdjustLock_;
std::map<std::vector<std::string>, PanelAdjustInfo> panelAdjust_;
std::mutex adjustInfoInitLock_;
uint64_t adjustInfoDisplayId_ = 0;
std::atomic<bool> isAdjustInfoInitialized_{ false };
std::atomic<bool> isIgnorePanelAdjustInitialized_{ false };
std::mutex ignoreAdjustInputTypeLock_;
std::vector<int32_t> ignoreAdjustInputTypes_;
std::mutex hotAreasLock_;
HotAreas hotAreas_;
std::mutex enhancedLayoutParamMutex_;
EnhancedLayoutParams enhancedLayoutParams_;
std::mutex keyboardLayoutParamsMutex_;
Rosen::KeyboardLayoutParams keyboardLayoutParams_;
std::mutex keyboardSizeLock_;
WindowSize keyboardSize_ { 0, 0 };
std::mutex windowListenerLock_;
sptr<Rosen::IWindowChangeListener> windowChangedListener_ = nullptr;
std::mutex heightCallbackMutex_;
CallbackFunc panelHeightCallback_ = nullptr;
std::mutex foldResizeParamMutex_;
LayoutParams resizePanelFoldParams_ {
{ FOLD_TOP, FOLD_LEFT, FOLD_RIGHT, FOLD_BOTTOM },
{ FOLD_TOP, FOLD_LEFT, FOLD_RIGHT, COMMON_BOTTOM }
};
std::mutex unfoldResizeParamMutex_;
LayoutParams resizePanelUnfoldParams_ {
{ UNFOLD_TOP, UNFOLD_LEFT, UNFOLD_RIGHT, UNFOLD_BOTTOM },
{ UNFOLD_TOP, UNFOLD_LEFT, UNFOLD_RIGHT, COMMON_BOTTOM }
};
std::atomic<bool> isWaitSetUiContent_ { true };
std::atomic<bool> isInEnhancedAdjust_{ false };
std::mutex immersiveModeMutex_;
ImmersiveMode immersiveMode_ { ImmersiveMode::NONE_IMMERSIVE };
std::mutex immersiveEffectMutex_;
ImmersiveEffect immersiveEffect_ { 0, GradientMode::NONE, FluidLightMode::NONE };
std::mutex changeYMutex_;
ChangeY changeY_;
std::mutex getInsetsMutex_;
std::mutex parseParamsMutex_;
std::mutex panelStatusChangeMutex_;
std::atomic<bool> hasSetSize_ { false };
std::atomic<bool> isExternalAdjusting_ { false };
bool isPortrait_ { true };
std::atomic<bool> hasAdjustWithoutScb_ { false };
std::mutex bindImeInfoLock_;
BoundImeInfo bindImeInfo_;
std::mutex adjustLayoutMutex_;
std::chrono::steady_clock::time_point adjustLayoutTime_;
std::atomic<bool> hasImfAdjust_ { false };
std::atomic<bool> hasJsAdjust_ { false };
std::atomic<bool> parseAdjustSuccess_ { true };
friend class JsPanel;
};
}
}
#endif