!1572 Add input start and stop notify clients app

Merge pull request !1572 from liweixing1994/master
This commit is contained in:
openharmony_ci 2024-11-10 13:06:43 +00:00 committed by Gitee
commit 3f63259932
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
22 changed files with 320 additions and 7 deletions

View File

@ -34,6 +34,10 @@ public:
{
return (eventFlag & EVENT_IME_HIDE_MASK) == EVENT_IME_HIDE_MASK;
}
inline static bool IsInputStatusChangedOn(uint32_t eventFlag)
{
return (eventFlag & EVENT_INPUT_STATUS_CHANGED_MASK) == EVENT_INPUT_STATUS_CHANGED_MASK;
}
};
} // namespace MiscServices
} // namespace OHOS

View File

@ -33,6 +33,8 @@ public:
ON_INPUT_STOP,
ON_SWITCH_INPUT,
ON_PANEL_STATUS_CHANGE,
ON_NOTIFY_INPUT_START, // IME start to input, no bind
ON_NOTIFY_INPUT_STOP, // IME stop to input
DEACTIVATE_CLIENT
};
@ -42,6 +44,8 @@ public:
virtual int32_t OnInputStop(bool isStopInactiveClient) = 0;
virtual int32_t OnSwitchInput(const Property &property, const SubProperty &subProperty) = 0;
virtual int32_t OnPanelStatusChange(const InputWindowStatus &status, const ImeWindowInfo &info) = 0;
virtual int32_t NotifyInputStart(uint32_t callingWndId) = 0;
virtual int32_t NotifyInputStop() = 0;
virtual void DeactivateClient() = 0;
};
} // namespace MiscServices

View File

@ -32,16 +32,20 @@ public:
IMF_API int32_t UnRegisterImeEventListener(uint32_t eventFlag, const std::shared_ptr<ImeEventListener> &listener);
int32_t OnImeChange(const Property &property, const SubProperty &subProperty);
int32_t OnPanelStatusChange(const InputWindowStatus &status, const ImeWindowInfo &info);
int32_t OnInputStart(uint32_t callingWndId);
int32_t OnInputStop();
private:
ImeEventMonitorManagerImpl();
~ImeEventMonitorManagerImpl();
static constexpr uint32_t MAX_EVENT_NUM = 3;
static constexpr uint32_t MAX_EVENT_NUM = 4;
int32_t OnImeShow(const ImeWindowInfo &info);
int32_t OnImeHide(const ImeWindowInfo &info);
std::set<std::shared_ptr<ImeEventListener>> GetListeners(uint32_t eventMask);
std::mutex lock_;
std::map<uint32_t, std::set<std::shared_ptr<ImeEventListener>>> listeners_{};
bool isInputStart_{ false };
uint32_t callingWindow_{ 0 };
};
} // namespace MiscServices
} // namespace OHOS

View File

@ -38,6 +38,8 @@ public:
int32_t OnInputStop(bool isStopInactiveClient) override;
int32_t OnSwitchInput(const Property &property, const SubProperty &subProperty) override;
int32_t OnPanelStatusChange(const InputWindowStatus &status, const ImeWindowInfo &info) override;
int32_t NotifyInputStart(uint32_t callingWndId) override;
int32_t NotifyInputStop() override;
void DeactivateClient() override;
private:

View File

@ -40,6 +40,8 @@ public:
int32_t OnInputStop(bool isStopInactiveClient) override;
int32_t OnSwitchInput(const Property &property, const SubProperty &subProperty) override;
int32_t OnPanelStatusChange(const InputWindowStatus &status, const ImeWindowInfo &info) override;
int32_t NotifyInputStart(uint32_t callingWndId) override;
int32_t NotifyInputStop() override;
void DeactivateClient() override;
private:
@ -48,6 +50,8 @@ private:
int32_t OnSwitchInputOnRemote(MessageParcel &data, MessageParcel &reply);
int32_t OnPanelStatusChangeOnRemote(MessageParcel &data, MessageParcel &reply);
int32_t DeactivateClientOnRemote(MessageParcel &data, MessageParcel &reply);
int32_t NotifyInputStartOnRemote(MessageParcel &data, MessageParcel &reply);
int32_t NotifyInputStopOnRemote(MessageParcel &data, MessageParcel &reply);
};
} // namespace MiscServices
} // namespace OHOS

View File

@ -81,6 +81,8 @@ public:
int32_t ShowCurrentInputDeprecated() override;
bool IsDefaultImeSet() override;
bool EnableIme(const std::string &bundleName) override;
// make app client know calling IMF window
int32_t SetCallingWindow(uint32_t windowId, sptr<IInputClient> client) override;
private:
static inline BrokerDelegator<InputMethodSystemAbilityProxy> delegator_;

View File

@ -61,6 +61,9 @@ int32_t ImeEventMonitorManagerImpl::RegisterImeEventListener(uint32_t eventFlag,
}
it->second.insert(listener);
}
if (isInputStart_ && EventStatusManager::IsInputStatusChangedOn(eventFlag)) {
listener->OnInputStart(callingWindow_);
}
return ErrorCode::NO_ERROR;
}
@ -121,6 +124,32 @@ int32_t ImeEventMonitorManagerImpl::OnPanelStatusChange(const InputWindowStatus
return ErrorCode::ERROR_BAD_PARAMETERS;
}
int32_t ImeEventMonitorManagerImpl::OnInputStart(uint32_t callingWndId)
{
isInputStart_ = true;
callingWindow_ = callingWndId;
auto listeners = GetListeners(EVENT_INPUT_STATUS_CHANGED_MASK);
for (const auto &listener : listeners) {
if (listener != nullptr) {
IMSA_HILOGD("listener start to callback, callingWndId: %{public}u", callingWndId);
listener->OnInputStart(callingWndId);
}
}
return ErrorCode::NO_ERROR;
}
int32_t ImeEventMonitorManagerImpl::OnInputStop()
{
isInputStart_ = false;
auto listeners = GetListeners(EVENT_INPUT_STATUS_CHANGED_MASK);
for (const auto &listener : listeners) {
if (listener != nullptr) {
listener->OnInputStop();
}
}
return ErrorCode::NO_ERROR;
}
int32_t ImeEventMonitorManagerImpl::OnImeShow(const ImeWindowInfo &info)
{
auto listeners = GetListeners(EVENT_IME_SHOW_MASK);

View File

@ -51,6 +51,19 @@ int32_t InputClientProxy::OnPanelStatusChange(const InputWindowStatus &status, c
});
}
int32_t InputClientProxy::NotifyInputStart(uint32_t callingWndId)
{
IMSA_HILOGD("InputClientProxy::NotifyInputStart");
return SendRequest(ON_NOTIFY_INPUT_START, [callingWndId](MessageParcel &data) {
return ITypesUtil::Marshal(data, callingWndId);
});
}
int32_t InputClientProxy::NotifyInputStop()
{
IMSA_HILOGD("InputClientProxy::NotifyInputStop");
return SendRequest(ON_NOTIFY_INPUT_STOP, nullptr);
}
void InputClientProxy::DeactivateClient()
{
SendRequest(DEACTIVATE_CLIENT, nullptr, nullptr, MessageOption::TF_ASYNC);

View File

@ -61,6 +61,12 @@ int32_t InputClientStub::OnRemoteRequest(uint32_t code, MessageParcel &data, Mes
case DEACTIVATE_CLIENT: {
return DeactivateClientOnRemote(data, reply);
}
case ON_NOTIFY_INPUT_START: {
return NotifyInputStartOnRemote(data, reply);
}
case ON_NOTIFY_INPUT_STOP: {
return NotifyInputStopOnRemote(data, reply);
}
default:
return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
}
@ -115,6 +121,22 @@ int32_t InputClientStub::DeactivateClientOnRemote(MessageParcel &data, MessagePa
return reply.WriteInt32(ErrorCode::NO_ERROR) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
}
int32_t InputClientStub::NotifyInputStartOnRemote(MessageParcel &data, MessageParcel &reply)
{
uint32_t callingWndId = 0;
if (!ITypesUtil::Unmarshal(data, callingWndId)) {
IMSA_HILOGE("read message parcel failed!");
return ErrorCode::ERROR_EX_PARCELABLE;
}
return reply.WriteInt32(NotifyInputStart(callingWndId)) ?
ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
}
int32_t InputClientStub::NotifyInputStopOnRemote(MessageParcel &data, MessageParcel &reply)
{
return reply.WriteInt32(NotifyInputStop()) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
}
int32_t InputClientStub::OnInputReady(const sptr<IRemoteObject> &agent)
{
return ErrorCode::NO_ERROR;
@ -136,6 +158,16 @@ int32_t InputClientStub::OnPanelStatusChange(const InputWindowStatus &status, co
return ImeEventMonitorManagerImpl::GetInstance().OnPanelStatusChange(status, info);
}
int32_t InputClientStub::NotifyInputStart(uint32_t callingWndId)
{
return ImeEventMonitorManagerImpl::GetInstance().OnInputStart(callingWndId);
}
int32_t InputClientStub::NotifyInputStop()
{
return ImeEventMonitorManagerImpl::GetInstance().OnInputStop();
}
void InputClientStub::DeactivateClient()
{
InputMethodController::GetInstance()->DeactivateClient();

View File

@ -34,6 +34,7 @@
#include "sys/prctl.h"
#include "system_ability_definition.h"
#include "system_cmd_channel_stub.h"
#include "ime_event_monitor_manager_impl.h"
namespace OHOS {
namespace MiscServices {
@ -556,6 +557,8 @@ int32_t InputMethodController::HideInput(sptr<IInputClient> &client)
void InputMethodController::OnRemoteSaDied(const wptr<IRemoteObject> &remote)
{
IMSA_HILOGI("input method service death.");
// imf sa died, current client callback inputStop
ImeEventMonitorManagerImpl::GetInstance().OnInputStop();
auto textListener = GetTextListener();
if (textListener != nullptr && textConfig_.inputAttribute.isTextPreviewSupported) {
IMSA_HILOGD("finish text preview.");
@ -900,6 +903,10 @@ int32_t InputMethodController::SetCallingWindow(uint32_t windowId)
}
IMSA_HILOGI("windowId: %{public}d.", windowId);
agent->SetCallingWindow(windowId);
auto proxy = GetSystemAbilityProxy();
if (proxy != nullptr) {
proxy->SetCallingWindow(windowId, clientInfo_.client);
}
return ErrorCode::NO_ERROR;
}

View File

@ -185,6 +185,17 @@ bool InputMethodSystemAbilityProxy::EnableIme(const std::string &bundleName)
return enableIme;
}
int32_t InputMethodSystemAbilityProxy::SetCallingWindow(uint32_t windowId, sptr<IInputClient> client)
{
IMSA_HILOGI("proxy setCallingWindow enter");
if (client == nullptr) {
IMSA_HILOGE("nullptr client");
return ErrorCode::ERROR_EX_NULL_POINTER;
}
return SendRequest(static_cast<uint32_t>(InputMethodInterfaceCode::SET_CALLING_WINDOW),
[windowId, client](MessageParcel &data) { return ITypesUtil::Marshal(data, windowId, client->AsObject()); });
}
int32_t InputMethodSystemAbilityProxy::ListInputMethod(InputMethodStatus status, std::vector<Property> &props)
{
return SendRequest(

View File

@ -24,12 +24,15 @@ namespace MiscServices {
constexpr uint32_t EVENT_IME_CHANGE_MASK = 1u;
constexpr uint32_t EVENT_IME_SHOW_MASK = 1u << 1u;
constexpr uint32_t EVENT_IME_HIDE_MASK = 1u << 2u;
constexpr uint32_t EVENT_INPUT_STATUS_CHANGED_MASK = 1u << 3u; // OnInputStart and OnInputStop
class ImeEventListener {
public:
virtual ~ImeEventListener() = default;
virtual void OnImeChange(const Property &property, const SubProperty &subProperty){};
virtual void OnImeShow(const ImeWindowInfo &info){};
virtual void OnImeHide(const ImeWindowInfo &info){};
virtual void OnInputStart(uint32_t callingWndId) {};
virtual void OnInputStop() {};
};
} // namespace MiscServices
} // namespace OHOS

View File

@ -38,7 +38,8 @@ public:
/**
* @brief Register Ime Event Listener.
*
* This function is used to Register Ime Event Listener, only IME_SHOW and IME_HIDE supported at present
* This function is used to Register Ime Event Listener, only IME_SHOW, IME_HIDE,
* INPUT_STATUS_CHANGED supported at present
*
* @param eventFlag Indicates the flag of the ime event to be registered
* @param listener Indicates the the listener to be registered.
@ -50,7 +51,8 @@ public:
/**
* @brief UnRegister Ime Event Listener.
*
* This function is used to UnRegister Ime Event Listener, only IME_SHOW and IME_HIDE supported at present
* This function is used to UnRegister Ime Event Listener, only IME_SHOW and IME_HIDE,
* INPUT_STATUS_CHANGED supported at present
*
* @param types Indicates the flag of the ime event to be unRegistered
* @param listener Indicates the the listener to be unregistered.
@ -60,7 +62,8 @@ public:
IMF_API int32_t UnRegisterImeEventListener(uint32_t eventFlag, const std::shared_ptr<ImeEventListener> &listener);
private:
static constexpr uint32_t ALL_EVENT_MASK = EVENT_IME_SHOW_MASK | EVENT_IME_HIDE_MASK;
static constexpr uint32_t ALL_EVENT_MASK = EVENT_IME_SHOW_MASK | EVENT_IME_HIDE_MASK |
EVENT_INPUT_STATUS_CHANGED_MASK;
ImeEventMonitorManager();
~ImeEventMonitorManager();
bool IsParamValid(uint32_t eventFlag, const std::shared_ptr<ImeEventListener> &listener);

View File

@ -81,6 +81,8 @@ public:
// Deprecated because of no permission check, and keep for compatibility
virtual int32_t HideCurrentInputDeprecated() = 0;
virtual int32_t ShowCurrentInputDeprecated() = 0;
virtual int32_t SetCallingWindow(uint32_t windowId, sptr<IInputClient> client) = 0;
};
} // namespace MiscServices
} // namespace OHOS

View File

@ -74,6 +74,7 @@ public:
int32_t UnRegisteredProxyIme(UnRegisteredType type, const sptr<IInputMethodCore> &core) override;
int32_t PanelStatusChange(const InputWindowStatus &status, const ImeWindowInfo &info) override;
int32_t UpdateListenEventFlag(InputClientInfo &clientInfo, uint32_t eventFlag) override;
int32_t SetCallingWindow(uint32_t windowId, sptr<IInputClient> client) override;
bool IsCurrentIme() override;
bool IsInputTypeSupported(InputType type) override;
bool IsCurrentImeByPid(int32_t pid) override;

View File

@ -109,6 +109,8 @@ private:
int32_t InitConnectOnRemote(MessageParcel &data, MessageParcel &reply);
int32_t SetCallingWindowOnRemote(MessageParcel &data, MessageParcel &reply);
using RequestHandler = int32_t (InputMethodSystemAbilityStub::*)(MessageParcel &, MessageParcel &);
static inline constexpr RequestHandler HANDLERS[static_cast<uint32_t>(InputMethodInterfaceCode::IMS_CMD_END)] = {
&InputMethodSystemAbilityStub::InvalidRequest,
@ -184,6 +186,8 @@ private:
&InputMethodSystemAbilityStub::IsDefaultImeSetOnRemote,
[static_cast<uint32_t>(InputMethodInterfaceCode::ENABLE_IME)] =
&InputMethodSystemAbilityStub::EnableImeOnRemote,
[static_cast<uint32_t>(InputMethodInterfaceCode::SET_CALLING_WINDOW)] =
&InputMethodSystemAbilityStub::SetCallingWindowOnRemote,
};
};
} // namespace OHOS::MiscServices

View File

@ -57,6 +57,8 @@ enum class InputMethodInterfaceCode {
INIT_CONNECT,
IS_DEFAULT_IME_SET,
ENABLE_IME,
SET_CALLING_WINDOW,
IMS_CMD_END,
};
} // namespace MiscServices

View File

@ -147,6 +147,7 @@ public:
int32_t SetInputType();
std::shared_ptr<ImeNativeCfg> GetImeNativeCfg(int32_t userId, const std::string &bundleName,
const std::string &subName);
int32_t OnSetCallingWindow(uint32_t callingWindowId, sptr<IInputClient> client);
private:
struct ResetManager {
@ -242,6 +243,10 @@ private:
bool HandleFirstStart(const std::shared_ptr<ImeNativeCfg> &ime, bool isStopCurrentIme);
bool HandleStartImeTimeout(const std::shared_ptr<ImeNativeCfg> &ime);
bool GetInputTypeToStart(std::shared_ptr<ImeNativeCfg> &imeToStart);
// from service notify clients input start and stop
int32_t NotifyInputStartToClients(uint32_t callingWndId);
int32_t NotifyInputStopToClients();
bool IsNotifyInputStop(const sptr<IInputClient> &client);
std::mutex imeStartLock_;
BlockData<bool> isImeStarted_{ MAX_IME_START_TIME, false };

View File

@ -539,7 +539,8 @@ int32_t InputMethodSystemAbility::PanelStatusChange(const InputWindowStatus &sta
int32_t InputMethodSystemAbility::UpdateListenEventFlag(InputClientInfo &clientInfo, uint32_t eventFlag)
{
IMSA_HILOGI("finalEventFlag: %{public}u, eventFlag: %{public}u.", clientInfo.eventFlag, eventFlag);
if (EventStatusManager::IsImeHideOn(eventFlag) || EventStatusManager::IsImeShowOn(eventFlag)) {
if (EventStatusManager::IsImeHideOn(eventFlag) || EventStatusManager::IsImeShowOn(eventFlag) ||
EventStatusManager::IsInputStatusChangedOn(eventFlag)) {
if (!identityChecker_->IsSystemApp(IPCSkeleton::GetCallingFullTokenID()) &&
!identityChecker_->IsNativeSa(IPCSkeleton::GetCallingTokenID())) {
IMSA_HILOGE("not system application!");
@ -559,6 +560,18 @@ int32_t InputMethodSystemAbility::UpdateListenEventFlag(InputClientInfo &clientI
return session->OnUpdateListenEventFlag(clientInfo);
}
int32_t InputMethodSystemAbility::SetCallingWindow(uint32_t windowId, sptr<IInputClient> client)
{
IMSA_HILOGD("IMF SA setCallingWindow enter");
auto callingUserId = GetCallingUserId();
auto session = UserSessionManager::GetInstance().GetUserSession(callingUserId);
if (session == nullptr) {
IMSA_HILOGE("%{public}d session is nullptr!", callingUserId);
return ErrorCode::ERROR_NULL_POINTER;
}
return session->OnSetCallingWindow(windowId, client);
}
bool InputMethodSystemAbility::IsCurrentIme()
{
return IsCurrentIme(GetCallingUserId());

View File

@ -328,6 +328,22 @@ int32_t InputMethodSystemAbilityStub::UpdateListenEventFlagOnRemote(MessageParce
return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
}
int32_t InputMethodSystemAbilityStub::SetCallingWindowOnRemote(MessageParcel &data, MessageParcel &reply)
{
auto clientObject = data.ReadRemoteObject();
if (clientObject == nullptr) {
IMSA_HILOGE("clientObject is nullptr!");
return ErrorCode::ERROR_EX_PARCELABLE;
}
uint32_t windowId = 0;
if (!ITypesUtil::Unmarshal(data, windowId)) {
IMSA_HILOGE("unmarshal failed!");
return ErrorCode::ERROR_EX_PARCELABLE;
}
return ITypesUtil::Marshal(reply, SetCallingWindow(windowId, iface_cast<IInputClient>(clientObject))) ?
ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
}
int32_t InputMethodSystemAbilityStub::ShowCurrentInputOnRemoteDeprecated(MessageParcel &data, MessageParcel &reply)
{
int32_t ret = ShowCurrentInputDeprecated();

View File

@ -232,6 +232,11 @@ int32_t PerUserSession::ShowKeyboard(const sptr<IInputClient> &currentClient)
*/
void PerUserSession::OnClientDied(sptr<IInputClient> remote)
{
IMSA_HILOGD("vkbtest onClientDied start.");
if (IsNotifyInputStop(remote)) {
IMSA_HILOGD("vkbtest ClientDie notify input stop");
NotifyInputStopToClients();
}
if (remote == nullptr) {
return;
}
@ -280,6 +285,8 @@ void PerUserSession::OnImeDied(const sptr<IInputMethodCore> &remote, ImeType typ
auto client = GetCurrentClient();
auto clientInfo = client != nullptr ? GetClientInfo(client->AsObject()) : nullptr;
if (clientInfo != nullptr && clientInfo->bindImeType == type) {
IMSA_HILOGD("vkbtest imeDied notify input stop");
NotifyInputStopToClients();
StopClientInput(clientInfo);
if (type == ImeType::IME) {
StartImeInImeDied();
@ -419,6 +426,8 @@ int32_t PerUserSession::OnRequestHideInput()
RemoveClient(inactiveClient, false, true);
}
RestoreCurrentImeSubType();
IMSA_HILOGD("vkbtest end requestHideInput");
NotifyInputStopToClients();
return ErrorCode::NO_ERROR;
}
@ -468,7 +477,17 @@ int32_t PerUserSession::OnPrepareInput(const InputClientInfo &clientInfo)
int32_t PerUserSession::OnReleaseInput(const sptr<IInputClient> &client)
{
IMSA_HILOGD("PerUserSession::OnReleaseInput start");
return RemoveClient(client, true);
bool isReady = IsNotifyInputStop(client);
int32_t ret = RemoveClient(client, true);
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGE("vkbtest remove client failed");
return ret;
}
if (isReady) {
IMSA_HILOGD("vkbtest notify input stop to clients");
NotifyInputStopToClients();
}
return ErrorCode::NO_ERROR;
}
int32_t PerUserSession::RemoveClient(const sptr<IInputClient> &client, bool isUnbindFromClient, bool isInactiveClient)
@ -602,6 +621,8 @@ int32_t PerUserSession::BindClientWithIme(const std::shared_ptr<InputClientInfo>
{ { UpdateFlag::BINDIMETYPE, type }, { UpdateFlag::ISSHOWKEYBOARD, clientInfo->isShowKeyboard },
{ UpdateFlag::STATE, ClientState::ACTIVE } });
ReplaceCurrentClient(clientInfo->client);
int32_t errorCode = NotifyInputStartToClients(clientInfo->config.windowId);
IMSA_HILOGD("vkbtest bind notify ret: %{public}d.", errorCode);
return ErrorCode::NO_ERROR;
}
@ -683,6 +704,13 @@ int32_t PerUserSession::OnSetCoreAndAgent(const sptr<IInputMethodCore> &core, co
}
bool isStarted = true;
isImeStarted_.SetValue(isStarted);
// if client exist, execute notify input start callback
if (client != nullptr && clientInfo != nullptr) {
ret = NotifyInputStartToClients(clientInfo->config.windowId);
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGE("notifyInputStartToClients failed, ret: %{public}d.", ret);
}
}
return ErrorCode::NO_ERROR;
}
@ -1160,6 +1188,82 @@ int32_t PerUserSession::OnUpdateListenEventFlag(const InputClientInfo &clientInf
return ErrorCode::NO_ERROR;
}
int32_t PerUserSession::OnSetCallingWindow(uint32_t callingWindowId, sptr<IInputClient> client)
{
IMSA_HILOGD("OnSetCallingWindow enter");
if (!IsSameClient(client, GetCurrentClient())) {
IMSA_HILOGE("client is not current client!");
return ErrorCode::ERROR_CLIENT_NOT_FOCUSED;
}
if (client == nullptr) {
IMSA_HILOGE("nullptr client!");
return ErrorCode::ERROR_CLIENT_NULL_POINTER;
}
auto clientInfo = GetClientInfo(client->AsObject());
if (clientInfo == nullptr) {
IMSA_HILOGE("nullptr clientInfo!");
return ErrorCode::ERROR_CLIENT_NULL_POINTER;
}
// if windowId change, refresh windowId info and notify clients input start;
if (clientInfo->config.windowId != callingWindowId) {
IMSA_HILOGD("windowId changed, refresh windowId info and notify clients input start.");
clientInfo->config.windowId = callingWindowId;
return NotifyInputStartToClients(callingWindowId);
}
return ErrorCode::NO_ERROR;
}
int32_t PerUserSession::NotifyInputStartToClients(uint32_t callingWndId)
{
IMSA_HILOGD("NotifyInputStartToClients enter");
auto clientMap = GetClientMap();
for (const auto &client : clientMap) {
auto clientInfo = client.second;
if (clientInfo == nullptr || clientInfo->client == nullptr ||
!EventStatusManager::IsInputStatusChangedOn(clientInfo->eventFlag)) {
IMSA_HILOGE("nullptr clientInfo or no need to notify");
continue;
}
int32_t ret = clientInfo->client->NotifyInputStart(callingWndId);
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGE("failed to notify OnInputStart, errorCode: %{public}d", ret);
continue;
}
}
return ErrorCode::NO_ERROR;
}
int32_t PerUserSession::NotifyInputStopToClients()
{
IMSA_HILOGD("NotifyInputStopToClients enter");
auto clientMap = GetClientMap();
for (const auto &client : clientMap) {
auto clientInfo = client.second;
if (clientInfo == nullptr || clientInfo->client == nullptr ||
!EventStatusManager::IsInputStatusChangedOn(clientInfo->eventFlag)) {
IMSA_HILOGE("nullptr clientInfo or no need to notify");
continue;
}
int32_t ret = clientInfo->client->NotifyInputStop();
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGE("failed to notify OnInputStop, errorCode: %{public}d", ret);
continue;
}
}
return ErrorCode::NO_ERROR;
}
bool PerUserSession::IsNotifyInputStop(const sptr<IInputClient> &client)
{
if (IsSameClient(client, GetCurrentClient())) {
return true;
}
if (IsSameClient(client, GetInactiveClient()) && GetCurrentClient() == nullptr) {
return true;
}
return false;
}
bool PerUserSession::IsImeStartInBind(ImeType bindImeType, ImeType startImeType)
{
return startImeType == ImeType::IME && bindImeType == ImeType::IME;
@ -1340,6 +1444,8 @@ int32_t PerUserSession::RemoveCurrentClient()
IMSA_HILOGE("currentClient is nullptr!");
return ErrorCode::ERROR_CLIENT_NULL_POINTER;
}
IMSA_HILOGD("vkbtest abnormal remove current client");
NotifyInputStopToClients();
return RemoveClient(currentClient, false);
}

View File

@ -102,7 +102,7 @@ HWTEST_F(ImeEventMonitorManagerTest, testRegisterImeEventListener_003, TestSize.
auto listener = std::make_shared<ImeSettingListenerTestImpl>();
auto ret = ImeEventMonitorManager::GetInstance().RegisterImeEventListener(15, listener);
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
EXPECT_EQ(ImeEventMonitorManagerImpl::GetInstance().listeners_.size(), 2);
EXPECT_EQ(ImeEventMonitorManagerImpl::GetInstance().listeners_.size(), 3);
auto it = ImeEventMonitorManagerImpl::GetInstance().listeners_.find(EVENT_IME_HIDE_MASK);
ASSERT_NE(it, ImeEventMonitorManagerImpl::GetInstance().listeners_.end());
it = ImeEventMonitorManagerImpl::GetInstance().listeners_.find(EVENT_IME_SHOW_MASK);
@ -462,6 +462,52 @@ HWTEST_F(ImeEventMonitorManagerTest, testUnRegisterImeEventListener_019, TestSiz
iter = it->second.find(listener1);
EXPECT_NE(iter, it->second.end());
}
/**
* @tc.name: testInputStatusChangedListener
* @tc.desc: register and unregister EVENT_INPUT_STATUS_CHANGED_MASK,
* there is no effect on EVENT_IME_SHOW_MASK and EVENT_HIDE_SHOW_MASK
* @tc.type: FUNC
*/
HWTEST_F(ImeEventMonitorManagerTest, testInputStatusChangedListener, TestSize.Level0)
{
IMSA_HILOGI("testInputStatusChangedListener start.");
auto listener = std::make_shared<ImeSettingListenerTestImpl>();
auto listener1 = std::make_shared<ImeSettingListenerTestImpl>();
auto ret = ImeEventMonitorManager::GetInstance().RegisterImeEventListener(
EVENT_IME_SHOW_MASK | EVENT_IME_HIDE_MASK, listener);
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
EXPECT_EQ(InputMethodController::GetInstance()->clientInfo_.eventFlag, 6);
ret = ImeEventMonitorManager::GetInstance().RegisterImeEventListener(EVENT_INPUT_STATUS_CHANGED_MASK, listener);
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
EXPECT_EQ(InputMethodController::GetInstance()->clientInfo_.eventFlag, 14);
ret = ImeEventMonitorManager::GetInstance().UnRegisterImeEventListener(EVENT_INPUT_STATUS_CHANGED_MASK, listener);
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
EXPECT_EQ(InputMethodController::GetInstance()->clientInfo_.eventFlag, 6);
auto it = ImeEventMonitorManagerImpl::GetInstance().listeners_.find(EVENT_IME_HIDE_MASK);
ASSERT_NE(it, ImeEventMonitorManagerImpl::GetInstance().listeners_.end());
ASSERT_EQ(it->second.size(), 1);
auto iter = it->second.find(listener);
ret = ImeEventMonitorManager::GetInstance().RegisterImeEventListener(EVENT_INPUT_STATUS_CHANGED_MASK, listener1);
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
EXPECT_EQ(InputMethodController::GetInstance()->clientInfo_.eventFlag, 14);
it = ImeEventMonitorManagerImpl::GetInstance().listeners_.find(EVENT_INPUT_STATUS_CHANGED_MASK);
ASSERT_NE(it, ImeEventMonitorManagerImpl::GetInstance().listeners_.end());
ASSERT_EQ(it->second.size(), 1);
iter = it->second.find(listener1);
EXPECT_NE(iter, it->second.end());
ret = ImeEventMonitorManager::GetInstance().RegisterImeEventListener(EVENT_INPUT_STATUS_CHANGED_MASK, listener);
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
EXPECT_EQ(InputMethodController::GetInstance()->clientInfo_.eventFlag, 14);
it = ImeEventMonitorManagerImpl::GetInstance().listeners_.find(EVENT_INPUT_STATUS_CHANGED_MASK);
ASSERT_NE(it, ImeEventMonitorManagerImpl::GetInstance().listeners_.end());
ASSERT_EQ(it->second.size(), 2);
}
/********************************* all test is for innerkit above ***************************************************/
/**
* @tc.name: testRegisterImeEventListener_020