* Copyright (C) 2021-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 FRAMEWORKS_INPUTMETHOD_ABILITY_INCLUDE_INPUT_METHOD_ABILITY_H
#define FRAMEWORKS_INPUTMETHOD_ABILITY_INCLUDE_INPUT_METHOD_ABILITY_H
#include <thread>
#include "calling_window_info.h"
#include "concurrent_map.h"
#include "context.h"
#include "iinput_control_channel.h"
#include "iinput_data_channel.h"
#include "iinput_method_agent.h"
#include "iinput_method_core.h"
#include "iinput_method_system_ability.h"
#include "input_attribute.h"
#include "input_control_channel_proxy.h"
#include "input_data_channel_proxy.h"
#include "input_method_engine_listener.h"
#include "input_method_panel.h"
#include "input_method_types.h"
#include "input_method_utils.h"
#include "input_status_info.h"
#include "iremote_object.h"
#include "keyboard_listener.h"
#include "key_event_consumer_proxy.h"
#include "text_input_client_listener.h"
#include "msg_handler_callback_interface.h"
#include "private_command_interface.h"
#include "system_cmd_channel_proxy.h"
#include "inputmethod_message_handler.h"
#include "input_data_channel_proxy_wrap.h"
#include "ime_mirror_manager.h"
namespace OHOS {
namespace MiscServices {
class InputMethodAbility : public RefBase, public PrivateCommandInterface {
public:
static InputMethodAbility &GetInstance();
int32_t SetCoreAndAgent();
int32_t InitConnect();
int32_t RegisterProxyIme(uint64_t displayId);
int32_t UnregisterProxyIme(uint64_t displayId, UnRegisteredType type = UnRegisteredType::REMOVE_PROXY_IME);
int32_t BindImeMirror();
int32_t UnbindImeMirror();
int32_t InsertText(const std::string &text, const AsyncIpcCallBack &callback = nullptr);
void SetImeListener(std::shared_ptr<InputMethodEngineListener> imeListener);
std::shared_ptr<InputMethodEngineListener> GetImeListener();
void SetKdListener(std::shared_ptr<KeyboardListener> kdListener);
void SetTextInputClientListener(std::shared_ptr<TextInputClientListener> textInputClientListener);
int32_t DeleteForward(int32_t length, const AsyncIpcCallBack &callback = nullptr);
int32_t DeleteBackward(int32_t length, const AsyncIpcCallBack &callback = nullptr);
int32_t HideKeyboardSelf();
int32_t SendExtendAction(int32_t action, const AsyncIpcCallBack &callback = nullptr);
int32_t GetTextBeforeCursor(int32_t number, std::u16string &text, const AsyncIpcCallBack &callback = nullptr);
int32_t GetTextAfterCursor(int32_t number, std::u16string &text, const AsyncIpcCallBack &callback = nullptr);
int32_t SendFunctionKey(int32_t funcKey, const AsyncIpcCallBack &callback = nullptr);
int32_t MoveCursor(int32_t keyCode, const AsyncIpcCallBack &callback = nullptr);
int32_t SelectByRange(int32_t start, int32_t end, const AsyncIpcCallBack &callback = nullptr);
int32_t SelectByMovement(int32_t direction, const AsyncIpcCallBack &callback = nullptr);
int32_t DispatchKeyEvent(
const std::shared_ptr<MMI::KeyEvent> &keyEvent, uint64_t cbId, const sptr<IRemoteObject> &channelObject);
void SetCallingWindow(uint32_t rawEditorWindowId, const FocusedInfo &focusedInfo);
int32_t GetEnterKeyType(int32_t &keyType);
int32_t GetInputPattern(int32_t &inputPattern);
int32_t GetTextIndexAtCursor(int32_t &index, const AsyncIpcCallBack &callback = nullptr);
int32_t GetTextConfig(TextTotalConfig &textConfig);
int32_t AdjustKeyboard();
int32_t CreatePanel(const std::shared_ptr<AbilityRuntime::Context> &context, const PanelInfo &panelInfo,
std::shared_ptr<InputMethodPanel> &inputMethodPanel);
int32_t DestroyPanel(const std::shared_ptr<InputMethodPanel> &inputMethodPanel);
int32_t ShowPanel(const std::shared_ptr<InputMethodPanel> &inputMethodPanel);
int32_t HidePanel(const std::shared_ptr<InputMethodPanel> &inputMethodPanel);
bool IsCurrentIme();
bool IsEnable(uint64_t displayId);
bool IsCallbackRegistered(const std::string &type);
bool IsSystemApp();
InputType GetInputType();
int32_t ExitCurrentInputType();
int32_t IsPanelShown(const PanelInfo &panelInfo, bool &isShown);
int32_t GetSecurityMode(int32_t &security);
int32_t OnSecurityChange(int32_t security);
int32_t OnConnectSystemCmd(const sptr<IRemoteObject> &channel);
void OnClientInactive(const sptr<IRemoteObject> &channel);
void NotifyKeyboardHeight(uint32_t panelHeight, PanelFlag panelFlag);
int32_t SendPrivateCommand(const std::unordered_map<std::string, PrivateDataValue> &privateCommand,
bool validateDefaultIme = true) override;
int32_t ReceivePrivateCommand(const std::unordered_map<std::string, PrivateDataValue> &privateCommand) override;
bool IsDefaultIme();
int32_t GetCallingWindowInfo(CallingWindowInfo &windowInfo);
int32_t SetPreviewText(const std::string &text, const Range &range, const AsyncIpcCallBack &callback = nullptr);
int32_t FinishTextPreview(const AsyncIpcCallBack &callback = nullptr);
int32_t NotifyPanelStatus(bool isUseParameterFlag = false, PanelFlag panelFlag = FLG_FIXED,
bool isCheckFuncButton = false);
InputAttribute GetInputAttribute();
void OnSetInputType(InputType inputType, uint64_t displayId);
int32_t SendMessage(const ArrayBuffer &arrayBuffer);
int32_t RecvMessage(const ArrayBuffer &arrayBuffer);
int32_t RegisterMsgHandler(const std::shared_ptr<MsgHandlerCallbackInterface> &msgHandler = nullptr);
int32_t OnCallingDisplayIdChanged(uint64_t editorDisplayId, uint64_t keyboardDisplayId);
int32_t OnSendPrivateData(const std::unordered_map<std::string, PrivateDataValue> &privateCommand);
bool HandleUnconsumedKey(const std::shared_ptr<MMI::KeyEvent> &keyEvent);
int32_t OnResponse(uint64_t msgId, int32_t code, const ResponseData &data);
int32_t IsCapacitySupport(int32_t capacity, bool &isSupport);
AttachOptions GetAttachOptions();
int32_t HandleKeyEventResult(uint64_t cbId, bool consumeResult, const sptr<IRemoteObject> &channelObject);
void RemoveDeathRecipient();
void SetConfigurationUpdate(std::function<void(Rosen::DisplayId displayId)> configurationUpdate);
public:
int32_t StartInput(const InputClientInfo &clientInfo, bool isBindFromClient);
int32_t StopInput(sptr<IRemoteObject> channelObj, uint32_t sessionId, int32_t clientSessionId = -1);
int32_t ShowKeyboard(int32_t requestKeyboardReason);
int32_t HideKeyboard();
int32_t OnDiscardTypingText();
int32_t OnNotifyPreemption();
void OnInitInputControlChannel(sptr<IRemoteObject> channelObj);
void OnSetSubtype(SubProperty subProperty);
void OnCursorUpdate(int32_t positionX, int32_t positionY, int32_t height);
void OnSelectionChange(std::u16string text, int32_t oldBegin, int32_t oldEnd, int32_t newBegin, int32_t newEndg);
void OnAttributeChange(InputAttribute attribute);
void OnFunctionKey(int32_t funcKey);
SysPanelStatus GetSysPanelStatus();
int32_t OnStopInputService(bool isTerminateIme);
HiSysEventClientInfo GetBindClientInfo();
int32_t GetSoftKeyboardInfo(BoundImeInfo &imeInfo);
private:
std::mutex controlChannelLock_;
std::shared_ptr<InputControlChannelProxy> controlChannel_ = nullptr;
std::mutex dataChannelLock_;
sptr<IRemoteObject> dataChannelObject_ = nullptr;
std::shared_ptr<InputDataChannelProxyWrap> dataChannelProxyWrap_ = nullptr;
sptr<InputDeathRecipient> dataChannelDeathRecipient_{ nullptr };
std::mutex systemCmdChannelLock_;
sptr<SystemCmdChannelProxy> systemCmdChannelProxy_ = nullptr;
std::shared_ptr<InputMethodEngineListener> imeListener_;
std::shared_ptr<KeyboardListener> kdListener_;
std::shared_ptr<TextInputClientListener> textInputClientListener_;
std::mutex abilityLock_;
sptr<IInputMethodSystemAbility> abilityManager_ { nullptr };
sptr<InputDeathRecipient> deathRecipient_ { nullptr };
InputMethodAbility();
~InputMethodAbility();
InputMethodAbility(const InputMethodAbility &) = delete;
InputMethodAbility &operator=(const InputMethodAbility &) = delete;
sptr<IInputMethodSystemAbility> GetImsaProxy();
void OnRemoteSaDied(const wptr<IRemoteObject> &object);
sptr<SystemCmdChannelProxy> GetSystemCmdChannelProxy();
void ClearSystemCmdChannel();
void SetInputDataChannel(const sptr<IRemoteObject> &object);
std::shared_ptr<InputDataChannelProxyWrap> GetInputDataChannelProxyWrap();
std::shared_ptr<InputDataChannelProxy> GetInputDataChannelProxy();
void ClearDataChannel(const sptr<IRemoteObject> &channel);
void SetInputControlChannel(sptr<IRemoteObject> &object);
void ClearInputControlChannel();
std::shared_ptr<InputControlChannelProxy> GetInputControlChannel();
void Initialize();
int32_t InvokeStartInputCallbackWithInfoRestruct(const TextTotalConfig &textConfig, bool isNotifyInputStart);
int32_t InvokeStartInputCallback(const TextTotalConfig &textConfig, bool isNotifyInputStart);
void HandleRequestKeyboardReasonChanged(const RequestKeyboardReason &requestKeyboardReason);
void InvokeAttachOptionsCallback(const AttachOptions &options, bool isFirstNotify = false);
void SetAttachOptions(const AttachOptions &options);
void ClearAttachOptions();
int32_t HideKeyboard(Trigger trigger, uint32_t sessionId, int32_t clientSessionId = -1);
std::shared_ptr<InputMethodPanel> GetSoftKeyboardPanel();
flag will be changed before finishing show/hide */
int32_t ShowPanel(const std::shared_ptr<InputMethodPanel> &inputMethodPanel, PanelFlag flag, Trigger trigger);
int32_t HidePanel(const std::shared_ptr<InputMethodPanel> &inputMethodPanel, PanelFlag flag, Trigger trigger,
uint32_t sessionId, int32_t clientSessionId = -1);
void SetInputAttribute(const InputAttribute &inputAttribute);
void ClearInputAttribute();
void NotifyPanelStatusInfo(PanelStatusInfo &info);
int32_t HideKeyboardImplWithoutLock(int32_t cmdId, uint32_t sessionId, int32_t clientSessionId = -1);
int32_t ShowKeyboardWithoutLock(int32_t cmdId, InputStartScene scene);
int32_t ShowKeyboardImplWithoutLock(int32_t cmdId);
void NotifyPanelStatusInfo(PanelStatusInfo &info, std::shared_ptr<InputDataChannelProxy> &channelProxy);
void ClearInputType();
std::shared_ptr<MsgHandlerCallbackInterface> GetMsgHandlerCallback();
int32_t StartInputInner(const InputClientInfo &clientInfo, bool isBindFromClient);
bool NotifyInfoToWmsInStartInput(const TextTotalConfig &textConfig);
void SetBindClientInfo(const InputClientInfo &clientInfo);
void ClearBindClientInfo();
void ReportImeStartInput(int32_t eventCode, int32_t errCode, bool isShowKeyboard, int64_t consumeTime = -1);
void ClearBindInfo(const sptr<IRemoteObject> &channel);
void OnInputDataChannelDied(const sptr<IRemoteObject> &dataChannelObject);
void UpdatePrivateCommand(const std::unordered_map<std::string, PrivateDataValue> &privateCommand);
void PushPrivateCommand();
void SetSysPanelStatus(const SysPanelStatus &sysPanelStatus);
bool IsSystemPanelSupported();
void ConfigurationUpdate(Rosen::DisplayId displayId);
void NotifyInputStartToClients(InputStartScene scene, bool isShowKeyboard = true);
void NotifyInputStopToClients();
ConcurrentMap<PanelType, std::shared_ptr<InputMethodPanel>> panels_ {};
std::atomic_bool isBound_ { false };
std::atomic_bool isProxyIme_{ false };
sptr<IInputMethodCore> coreStub_ { nullptr };
sptr<IInputMethodAgent> agentStub_ { nullptr };
std::mutex imeCheckMutex_;
bool isCurrentIme_ = false;
double positionY_ = 0;
double height_ = 0;
std::mutex defaultImeCheckMutex_;
bool isDefaultIme_ = false;
std::mutex inputAttrLock_;
InputAttribute inputAttribute_ {};
std::recursive_mutex keyboardCmdLock_;
int32_t cmdId_ = 0;
std::mutex attachOptionsLock_;
AttachOptions attachOptions_;
std::mutex inputTypeLock_;
InputType inputType_ = InputType::NONE;
std::atomic<bool> isImeTerminating_ = false;
std::atomic_bool isShowAfterCreate_ { false };
std::atomic<int32_t> securityMode_ = -1;
std::mutex msgHandlerMutex_;
std::shared_ptr<MsgHandlerCallbackInterface> msgHandler_;
std::mutex systemAppCheckMutex_;
bool isSystemApp_ = false;
std::mutex bindClientInfoLock_;
HiSysEventClientInfo bindClientInfo_;
bool isInputStartNotified_ = false;
ImeMirrorManager imeMirrorMgr_;
std::mutex privateCommandLock_;
std::vector<std::unordered_map<std::string, PrivateDataValue>> privateCommandData_;
std::mutex sysPanelStatusLock_;
SysPanelStatus sysPanelStatus_ { InputType::NONE, 0, 0, 0 } ;
std::mutex isSysPanelSupportMutex_;
std::atomic<int32_t> isSysPanelSupport_ = 0;
bool IsDisplayChanged(uint64_t oldDisplayId, uint64_t newDisplayId);
std::function<void(Rosen::DisplayId displayId)> configurationUpdate_;
};
}
}
#endif