* Copyright (c) 2021-2025 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.
*/
#include "input_handler_manager.h"
#include "anr_handler.h"
#include "bytrace_adapter.h"
#include "multimodal_event_handler.h"
#include "multimodal_input_connect_manager.h"
#include "mmi_log.h"
#include "error_multimodal.h"
#undef MMI_LOG_TAG
#define MMI_LOG_TAG "InputHandlerManager"
namespace OHOS {
namespace MMI {
namespace {
constexpr int32_t DEVICE_TAGS { 1 };
constexpr int32_t THREE_FINGERS { 3 };
constexpr int32_t FOUR_FINGERS { 4 };
constexpr int32_t COMMON_PARAMETER_ERROR { -401 };
}
InputHandlerManager::InputHandlerManager()
{
monitorCallback_ =
[this] (int32_t eventId, int64_t actionTime) { return this->OnDispatchEventProcessed(eventId, actionTime); };
monitorCallbackConsume_ =
[this] (int32_t eventId, int64_t actionTime) {
return this->OnDispatchEventProcessed(eventId, actionTime, true);
};
}
int32_t InputHandlerManager::AddHandler(InputHandlerType handlerType, std::shared_ptr<IInputEventConsumer> consumer,
HandleEventType eventType, int32_t priority, uint32_t deviceTags)
{
CALL_DEBUG_ENTER;
CHKPR(consumer, INVALID_HANDLER_ID);
if (handlerType == InputHandlerType::INTERCEPTOR) {
eventType = HANDLE_EVENT_TYPE_NONE;
if ((deviceTags & CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_KEYBOARD)) != 0) {
eventType |= HANDLE_EVENT_TYPE_KEY;
}
if ((deviceTags & (CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_MAX) -
CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_KEYBOARD))) != 0) {
eventType |= HANDLE_EVENT_TYPE_POINTER;
}
}
std::lock_guard guard(mtxHandlers_);
CHKFR(((monitorHandlers_.size() + interHandlers_.size()) < MAX_N_INPUT_HANDLERS), ERROR_EXCEED_MAX_COUNT,
"The number of handlers exceeds the maximum");
int32_t handlerId = GetNextId();
CHKFR((handlerId != INVALID_HANDLER_ID), INVALID_HANDLER_ID, "Exceeded limit of 32-bit maximum number of integers");
CHKFR((eventType != HANDLE_EVENT_TYPE_NONE), INVALID_HANDLER_ID, "Invalid event type");
const HandleEventType currentType = GetEventType();
MMI_HILOGI("Register new handler:%{public}d, currentType:%{public}d, deviceTags:%{public}d,"
"handlerType:%{public}d", handlerId, currentType, deviceTags, handlerType);
uint32_t currentTags = GetDeviceTags();
if (RET_OK == AddLocal(handlerId, handlerType, eventType, priority, deviceTags, consumer)) {
MMI_HILOGD("New handler successfully registered, report to server");
const HandleEventType newType = GetEventType();
if (currentType != newType || ((currentTags & deviceTags) != deviceTags)) {
uint32_t allDeviceTags = GetDeviceTags();
MMI_HILOGI("The handlerType:%{public}d, newType:%{public}d, deviceTags:%{public}d, priority:%{public}d",
handlerType, newType, allDeviceTags, priority);
int32_t ret = AddToServer(handlerType, newType, priority, allDeviceTags);
if (ret != RET_OK) {
MMI_HILOGE("Add Handler:%{public}d:%{public}d to server failed, (eventType,deviceTag) current: "
"(%{public}d, %{public}d), new: (%{public}d, %{public}d), priority:%{public}d",
handlerType, handlerId, currentType, currentTags, newType, deviceTags, priority);
RemoveLocal(handlerId, handlerType, allDeviceTags);
return ret;
}
}
MMI_HILOGI("Finish add Handler:%{public}d:%{public}d, (eventType,deviceTag) current:"
" (%{public}d, %{public}d), new: (%{public}d, %{public}d), priority:%{public}d",
handlerType, handlerId, currentType, currentTags, newType, deviceTags, priority);
} else {
MMI_HILOGE("Add Handler:%{public}d:%{public}d local failed, (eventType,deviceTag,priority): "
"(%{public}d, %{public}d, %{public}d)", handlerType, handlerId, eventType, deviceTags, priority);
handlerId = INVALID_HANDLER_ID;
}
return handlerId;
}
#ifdef OHOS_BUILD_ENABLE_TOUCH_GESTURE
int32_t InputHandlerManager::AddGestureMonitor(
InputHandlerType handlerType, std::shared_ptr<IInputEventConsumer> consumer,
HandleEventType eventType, TouchGestureType gestureType, int32_t fingers)
{
CHKPR(consumer, INVALID_HANDLER_ID);
std::lock_guard guard(mtxHandlers_);
CHKFR(((monitorHandlers_.size() + interHandlers_.size()) < MAX_N_INPUT_HANDLERS), ERROR_EXCEED_MAX_COUNT,
"The number of handlers exceeds the maximum");
int32_t handlerId = GetNextId();
CHKFR((handlerId != INVALID_HANDLER_ID), INVALID_HANDLER_ID,
"Exceeded limit of 32-bit maximum number of integers");
CHKFR((eventType != HANDLE_EVENT_TYPE_NONE), INVALID_HANDLER_ID, "Invalid event type");
const auto isNew = IsNewToService(gestureType, fingers);
int32_t ret = AddGestureToLocal(handlerId, eventType, gestureType, fingers, consumer);
if (ret == RET_OK) {
if (isNew) {
MMI_HILOGI("Add TouchGesture(%{public}d, %{public}d) to service", gestureType, fingers);
ret = MULTIMODAL_INPUT_CONNECT_MGR->AddGestureMonitor(
InputHandlerType::MONITOR, HANDLE_EVENT_TYPE_TOUCH_GESTURE, gestureType, fingers);
if (ret != RET_OK) {
MMI_HILOGE("Add gesture handler:%{public}d to server failed, ret:%{public}d", gestureType, ret);
uint32_t deviceTags = 0;
RemoveLocal(handlerId, handlerType, deviceTags);
return ret;
}
}
MMI_HILOGI("Finish add gesture handler(%{public}d:%{public}d:%{public}d:%{public}d) to server",
handlerId, eventType, gestureType, fingers);
} else {
handlerId = ret;
}
return handlerId;
}
#endif
int32_t InputHandlerManager::AddHandler(InputHandlerType handlerType, std::shared_ptr<IInputEventConsumer> consumer,
std::vector<int32_t> actionsType)
{
CALL_DEBUG_ENTER;
CHKPR(consumer, INVALID_HANDLER_ID);
std::lock_guard guard(mtxHandlers_);
CHKFR(((actionsMonitorHandlers_.size() + monitorHandlers_.size() + interHandlers_.size()) <
MAX_N_INPUT_HANDLERS), ERROR_EXCEED_MAX_COUNT, "The number of handlers exceeds the maximum");
int32_t handlerId = GetNextId();
CHKFR((handlerId != INVALID_HANDLER_ID), INVALID_HANDLER_ID, "Exceeded limit of 32-bit maximum number of integers");
MMI_HILOGD("Register new handler:%{public}d", handlerId);
if (RET_OK == AddLocal(handlerId, handlerType, actionsType, consumer)) {
MMI_HILOGD("New handler successfully registered, report to server");
if (IsNeedAddToServer(actionsType)) {
MMI_HILOGD("The handlerType:%{public}d", handlerType);
int32_t ret = AddToServer(handlerType, HANDLE_EVENT_TYPE_NONE, 0, 0, actionsType);
if (ret != RET_OK) {
MMI_HILOGE("Add Handler:%{public}d:%{public}d to server failed", handlerType, handlerId);
RemoveLocalActions(handlerId, handlerType);
return ret;
}
}
MMI_HILOGI("Finish add Handler:%{public}d:%{public}d to server", handlerType, handlerId);
} else {
MMI_HILOGE("Add Handler:%{public}d:%{public}d local failed", handlerType, handlerId);
handlerId = INVALID_HANDLER_ID;
}
return handlerId;
}
#ifdef OHOS_BUILD_ENABLE_TOUCH_GESTURE
int32_t InputHandlerManager::RemoveGestureMonitor(int32_t handlerId, InputHandlerType handlerType)
{
std::lock_guard guard(mtxHandlers_);
auto iter = monitorHandlers_.find(handlerId);
if (iter == monitorHandlers_.end()) {
MMI_HILOGE("No handler(%{public}d) with specified", handlerId);
return RET_ERR;
}
const auto gestureHandler = iter->second.gestureHandler_;
monitorHandlers_.erase(iter);
if (IsNewToService(gestureHandler.gestureType, gestureHandler.fingers)) {
MMI_HILOGI("Remove TouchGesture(%{public}d, %{public}d) from service",
gestureHandler.gestureType, gestureHandler.fingers);
auto ret = MULTIMODAL_INPUT_CONNECT_MGR->RemoveGestureMonitor(
InputHandlerType::MONITOR, HANDLE_EVENT_TYPE_TOUCH_GESTURE,
gestureHandler.gestureType, gestureHandler.fingers);
if (ret != RET_OK) {
MMI_HILOGE("Remove gesture handler:%{public}d to server failed, ret:%{public}d",
gestureHandler.gestureType, ret);
return ret;
}
}
MMI_HILOGI("Finish remove gesture handler:%{public}d:%{public}d,(%{public}d,%{public}d)",
handlerType, handlerId, gestureHandler.gestureType, gestureHandler.fingers);
return RET_OK;
}
#endif
bool InputHandlerManager::IsNeedAddToServer(std::vector<int32_t> actionsType)
{
bool isNeedAddToServer = false;
for (auto action : actionsType) {
if (std::find(addToServerActions_.begin(), addToServerActions_.end(), action) == addToServerActions_.end()) {
addToServerActions_.push_back(action);
isNeedAddToServer = true;
}
}
return isNeedAddToServer;
}
int32_t InputHandlerManager::RemoveHandler(int32_t handlerId, InputHandlerType handlerType)
{
CALL_DEBUG_ENTER;
MMI_HILOGD("Unregister handler:%{public}d,type:%{public}d", handlerId, handlerType);
std::lock_guard guard(mtxHandlers_);
uint32_t deviceTags = 0;
auto iter = monitorHandlers_.find(handlerId);
bool isInterHandlers = false;
for (auto inter = interHandlers_.begin(); inter != interHandlers_.end(); ++inter) {
if (handlerId == inter->handlerId_) {
isInterHandlers = true;
break;
}
}
if (iter != monitorHandlers_.end() || isInterHandlers) {
const HandleEventType currentType = GetEventType();
uint32_t currentTags = GetDeviceTags();
int32_t ret = RemoveLocal(handlerId, handlerType, deviceTags);
const HandleEventType newType = GetEventType();
const int32_t newLevel = GetPriority();
const uint64_t newTags = GetDeviceTags();
if (ret == RET_OK && (currentType != newType || ((currentTags & deviceTags) != 0))) {
ret = RemoveFromServer(handlerType, newType, newLevel, newTags);
if (ret != RET_OK) {
return ret;
}
MMI_HILOGI("Remove Handler:%{public}d:%{public}d, (eventType,deviceTag): (%{public}d:%{public}d) ",
handlerType, handlerId, currentType, currentTags);
}
return ret;
}
auto it = actionsMonitorHandlers_.find(handlerId);
if (it != actionsMonitorHandlers_.end()) {
std::vector<int32_t> actionsType = it->second.actionsType_;
size_t currentSize = addToServerActions_.size();
int32_t ret = RemoveLocalActions(handlerId, handlerType);
size_t newSize = addToServerActions_.size();
if (ret == RET_OK && currentSize != newSize) {
ret = RemoveFromServer(handlerType, HANDLE_EVENT_TYPE_NONE, 0, 0, actionsType);
if (ret != RET_OK) {
return ret;
}
MMI_HILOGI("Remove Handler:%{public}d:%{public}d", handlerType, handlerId);
}
return ret;
}
return RET_ERR;
}
#ifdef OHOS_BUILD_ENABLE_TOUCH_GESTURE
int32_t InputHandlerManager::AddGestureToLocal(int32_t handlerId, HandleEventType eventType,
TouchGestureType gestureType, int32_t fingers, std::shared_ptr<IInputEventConsumer> consumer)
{
if ((eventType & HANDLE_EVENT_TYPE_TOUCH_GESTURE) != HANDLE_EVENT_TYPE_TOUCH_GESTURE) {
MMI_HILOGE("Illegal type:%{public}d", eventType);
return COMMON_PARAMETER_ERROR;
}
if (!CheckMonitorValid(gestureType, fingers)) {
MMI_HILOGE("Wrong number of fingers:%{public}d", fingers);
return COMMON_PARAMETER_ERROR;
}
for (const auto &[id, handler] : monitorHandlers_) {
if ((handler.eventType_ == HANDLE_EVENT_TYPE_TOUCH_GESTURE) &&
((handler.gestureHandler_.gestureType & gestureType) == gestureType) &&
((handler.gestureHandler_.fingers == ALL_FINGER_COUNT) || (handler.gestureHandler_.fingers == fingers)) &&
(handler.consumer_ == consumer)) {
MMI_HILOGW("Duplicate monitor of TouchGesture(%{public}u, %{puglic}d)", gestureType, fingers);
return RET_ERR;
}
}
InputHandlerManager::Handler handler {
.handlerId_ = handlerId,
.handlerType_ = InputHandlerType::MONITOR,
.eventType_ = eventType,
.consumer_ = consumer,
.gestureHandler_ {
.gestureType = gestureType,
.fingers = fingers
}
};
auto ret = monitorHandlers_.emplace(handlerId, handler);
if (!ret.second) {
MMI_HILOGE("Duplicate handler:%{public}d", handlerId);
return RET_ERR;
}
return RET_OK;
}
bool InputHandlerManager::IsNewToService(TouchGestureType gestureType, int32_t fingers) const
{
return std::all_of(monitorHandlers_.cbegin(), monitorHandlers_.cend(),
[gestureType, fingers](const auto &item) {
const auto &handler = item.second;
const auto &gestureHandler = handler.gestureHandler_;
return ((handler.eventType_ != HANDLE_EVENT_TYPE_TOUCH_GESTURE) ||
((gestureHandler.gestureType & gestureType) != gestureType) ||
((gestureHandler.fingers != ALL_FINGER_COUNT) &&
(gestureHandler.fingers != fingers)));
});
}
#endif
int32_t InputHandlerManager::AddLocal(int32_t handlerId, InputHandlerType handlerType, HandleEventType eventType,
int32_t priority, uint32_t deviceTags, std::shared_ptr<IInputEventConsumer> monitor)
{
InputHandlerManager::Handler handler {
.handlerId_ = handlerId,
.handlerType_ = handlerType,
.eventType_ = eventType,
.priority_ = priority,
.deviceTags_ = deviceTags,
.consumer_ = monitor,
};
if (handlerType == InputHandlerType::MONITOR) {
auto ret = monitorHandlers_.emplace(handler.handlerId_, handler);
if (!ret.second) {
MMI_HILOGE("Duplicate handler:%{public}d", handler.handlerId_);
return RET_ERR;
}
}
if (handlerType == InputHandlerType::INTERCEPTOR) {
auto iterIndex = interHandlers_.begin();
for (; iterIndex != interHandlers_.end(); ++iterIndex) {
if (handler.priority_ < iterIndex->priority_) {
break;
}
}
auto iter = interHandlers_.emplace(iterIndex, handler);
if (iter == interHandlers_.end()) {
MMI_HILOGE("Add new handler failed");
return RET_ERR;
}
}
return RET_OK;
}
int32_t InputHandlerManager::AddLocal(int32_t handlerId, InputHandlerType handlerType, std::vector<int32_t> actionsType,
std::shared_ptr<IInputEventConsumer> monitor)
{
InputHandlerManager::Handler handler{
.handlerId_ = handlerId,
.handlerType_ = handlerType,
.eventType_ = HANDLE_EVENT_TYPE_NONE,
.consumer_ = monitor,
.actionsType_ = actionsType,
};
if (handlerType == InputHandlerType::MONITOR) {
auto ret = actionsMonitorHandlers_.emplace(handler.handlerId_, handler);
if (!ret.second) {
MMI_HILOGE("Actions duplicate handler:%{public}d", handler.handlerId_);
return RET_ERR;
}
}
return RET_OK;
}
int32_t InputHandlerManager::AddToServer(InputHandlerType handlerType, HandleEventType eventType, int32_t priority,
uint32_t deviceTags, std::vector<int32_t> actionsType)
{
int32_t ret = MULTIMODAL_INPUT_CONNECT_MGR->AddInputHandler(handlerType,
eventType, priority, deviceTags, actionsType);
if (ret != RET_OK) {
MMI_HILOGE("Send to server failed, ret:%{public}d", ret);
}
return ret;
}
int32_t InputHandlerManager::RemoveLocal(int32_t handlerId, InputHandlerType handlerType, uint32_t &deviceTags)
{
if (handlerType == InputHandlerType::MONITOR) {
auto iter = monitorHandlers_.find(handlerId);
if (iter == monitorHandlers_.end()) {
MMI_HILOGE("No handler with specified");
return RET_ERR;
}
if (handlerType != iter->second.handlerType_) {
MMI_HILOGE("Unmatched handler type, InputHandlerType:%{public}d,FindHandlerType:%{public}d", handlerType,
iter->second.handlerType_);
return RET_ERR;
}
monitorHandlers_.erase(iter);
}
if (handlerType == InputHandlerType::INTERCEPTOR) {
for (auto it = interHandlers_.begin(); it != interHandlers_.end(); ++it) {
if (handlerId == it->handlerId_) {
deviceTags = it->deviceTags_;
interHandlers_.erase(it);
break;
}
}
}
return RET_OK;
}
void InputHandlerManager::UpdateAddToServerActions()
{
std::vector<int32_t> addToServerActions;
for (const auto &[key, value] : actionsMonitorHandlers_) {
for (auto action : value.actionsType_) {
if (std::find(addToServerActions.begin(), addToServerActions.end(), action) ==
addToServerActions.end()) {
addToServerActions.push_back(action);
}
}
}
addToServerActions_.clear();
addToServerActions_ = addToServerActions;
}
int32_t InputHandlerManager::RemoveLocalActions(int32_t handlerId, InputHandlerType handlerType)
{
if (handlerType == InputHandlerType::MONITOR) {
auto iter = actionsMonitorHandlers_.find(handlerId);
if (iter == actionsMonitorHandlers_.end()) {
MMI_HILOGE("No handler with specified");
return RET_ERR;
}
if (handlerType != iter->second.handlerType_) {
MMI_HILOGE("Unmatched handler type, FindHandlerType:%{public}d", iter->second.handlerType_);
return RET_ERR;
}
actionsMonitorHandlers_.erase(iter);
UpdateAddToServerActions();
}
return RET_OK;
}
int32_t InputHandlerManager::RemoveFromServer(InputHandlerType handlerType, HandleEventType eventType, int32_t priority,
uint32_t deviceTags, std::vector<int32_t> actionsType)
{
int32_t ret = MULTIMODAL_INPUT_CONNECT_MGR->RemoveInputHandler(handlerType, eventType,
priority, deviceTags, actionsType);
if (ret != 0) {
MMI_HILOGE("Send to server failed, ret:%{public}d", ret);
}
return ret;
}
int32_t InputHandlerManager::GetNextId()
{
if (nextId_ == std::numeric_limits<int32_t>::max()) {
MMI_HILOGE("Exceeded limit of 32-bit maximum number of integers");
return INVALID_HANDLER_ID;
}
return nextId_++;
}
std::shared_ptr<IInputEventConsumer> InputHandlerManager::FindHandler(int32_t handlerId)
{
if (GetHandlerType() == InputHandlerType::MONITOR) {
auto iter = monitorHandlers_.find(handlerId);
if (iter != monitorHandlers_.end()) {
return iter->second.consumer_;
}
}
if (GetHandlerType() == InputHandlerType::INTERCEPTOR) {
for (const auto &item : interHandlers_) {
if (item.handlerId_ == handlerId) {
return item.consumer_;
}
}
}
return nullptr;
}
#ifdef OHOS_BUILD_ENABLE_KEYBOARD
void InputHandlerManager::OnInputEvent(std::shared_ptr<KeyEvent> keyEvent, uint32_t deviceTags)
{
CHK_PID_AND_TID();
CHKPV(keyEvent);
BytraceAdapter::StartBytrace(keyEvent, BytraceAdapter::TRACE_STOP, BytraceAdapter::KEY_INTERCEPT_EVENT);
if (GetHandlerType() == InputHandlerType::MONITOR) {
std::map<int32_t, Handler> tempMonitorHandlers;
{
std::lock_guard guard(mtxHandlers_);
tempMonitorHandlers = monitorHandlers_;
}
for (const auto &item : tempMonitorHandlers) {
if ((item.second.eventType_ & HANDLE_EVENT_TYPE_KEY) != HANDLE_EVENT_TYPE_KEY) {
continue;
}
int32_t handlerId = item.first;
std::shared_ptr<IInputEventConsumer> consumer = item.second.consumer_;
CHKPV(consumer);
{
std::lock_guard guard(mtxHandlers_);
auto iter = monitorHandlers_.find(handlerId);
if (iter == monitorHandlers_.end()) {
MMI_HILOGE("No handler with specified");
continue;
}
}
consumer->OnInputEvent(keyEvent);
MMI_HILOG_DISPATCHD("Key event id:%{public}d keyCode:%{private}d",
handlerId, keyEvent->GetKeyCode());
}
}
if (GetHandlerType() == InputHandlerType::INTERCEPTOR) {
std::lock_guard guard(mtxHandlers_);
for (const auto &item : interHandlers_) {
if ((item.eventType_ & HANDLE_EVENT_TYPE_KEY) != HANDLE_EVENT_TYPE_KEY) {
continue;
}
int32_t handlerId = item.handlerId_;
std::shared_ptr<IInputEventConsumer> consumer = item.consumer_;
CHKPV(consumer);
consumer->OnInputEvent(keyEvent);
MMI_HILOG_DISPATCHD("Key event id:%{public}d keyCode:%{private}d",
handlerId, keyEvent->GetKeyCode());
break;
}
}
}
#endif
#if defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)
bool InputHandlerManager::CheckInputDeviceSource(
const std::shared_ptr<PointerEvent> pointerEvent, uint32_t deviceTags) const
{
if ((pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_TOUCHSCREEN) &&
((deviceTags & CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_TOUCH)) ||
(deviceTags & CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_TABLET_TOOL)))) {
return true;
} else if ((pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_MOUSE) &&
(deviceTags & CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_POINTER))) {
return true;
} else if ((pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_TOUCHPAD) &&
(deviceTags & CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_POINTER))) {
return true;
}
return false;
}
void InputHandlerManager::GetConsumerInfos(std::shared_ptr<PointerEvent> pointerEvent, uint32_t deviceTags,
std::map<int32_t, std::shared_ptr<IInputEventConsumer>> &consumerInfos)
{
std::lock_guard guard(mtxHandlers_);
int32_t consumerCount = 0;
if (GetHandlerType() == InputHandlerType::MONITOR) {
lastPointerEvent_ = std::make_shared<PointerEvent>(*pointerEvent);
consumerCount = GetMonitorConsumerInfos(pointerEvent, consumerInfos);
}
if (GetHandlerType() == InputHandlerType::INTERCEPTOR) {
for (const auto &item : interHandlers_) {
if ((item.eventType_ & HANDLE_EVENT_TYPE_POINTER) != HANDLE_EVENT_TYPE_POINTER) {
continue;
}
if (((deviceTags & item.deviceTags_) == item.deviceTags_) &&
!CheckInputDeviceSource(pointerEvent, item.deviceTags_)) {
continue;
}
int32_t handlerId = item.handlerId_;
std::shared_ptr<IInputEventConsumer> consumer = item.consumer_;
CHKPV(consumer);
auto ret = consumerInfos.emplace(handlerId, consumer);
if (!ret.second) {
MMI_HILOGI("Duplicate handler:%{public}d", handlerId);
continue;
}
consumerCount++;
break;
}
}
if (consumerCount == 0) {
MMI_HILOGD("All task post failed");
return;
}
int32_t tokenType = MULTIMODAL_INPUT_CONNECT_MGR->GetTokenType();
if (tokenType != TokenType::TOKEN_HAP && tokenType != TokenType::TOKEN_SYSTEM_HAP) {
return;
}
AddMouseEventId(pointerEvent);
}
void InputHandlerManager::AddMouseEventId(std::shared_ptr<PointerEvent> pointerEvent)
{
if (pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_MOUSE) {
mouseEventIds_.emplace(pointerEvent->GetId());
}
}
bool InputHandlerManager::IsPinchType(std::shared_ptr<PointerEvent> pointerEvent)
{
CHKPF(pointerEvent);
if (pointerEvent->GetSourceType() != PointerEvent::SOURCE_TYPE_MOUSE &&
pointerEvent->GetSourceType() != PointerEvent::SOURCE_TYPE_TOUCHPAD) {
return false;
}
if ((pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_AXIS_BEGIN &&
pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_AXIS_UPDATE &&
pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_AXIS_END)) {
return false;
}
return true;
}
bool InputHandlerManager::IsRotateType(std::shared_ptr<PointerEvent> pointerEvent)
{
CHKPF(pointerEvent);
if (pointerEvent->GetSourceType() != PointerEvent::SOURCE_TYPE_MOUSE ||
(pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_ROTATE_BEGIN &&
pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_ROTATE_UPDATE &&
pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_ROTATE_END)) {
return false;
}
return true;
}
bool InputHandlerManager::IsThreeFingersSwipeType(std::shared_ptr<PointerEvent> pointerEvent)
{
CHKPF(pointerEvent);
if (pointerEvent->GetSourceType() != PointerEvent::SOURCE_TYPE_TOUCHPAD ||
pointerEvent->GetFingerCount() != THREE_FINGERS ||
(pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_SWIPE_BEGIN &&
pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_SWIPE_UPDATE &&
pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_SWIPE_END)) {
return false;
}
return true;
}
bool InputHandlerManager::IsFourFingersSwipeType(std::shared_ptr<PointerEvent> pointerEvent)
{
CHKPF(pointerEvent);
if (pointerEvent->GetSourceType() != PointerEvent::SOURCE_TYPE_TOUCHPAD ||
pointerEvent->GetFingerCount() != FOUR_FINGERS ||
(pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_SWIPE_BEGIN &&
pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_SWIPE_UPDATE &&
pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_SWIPE_END)) {
return false;
}
return true;
}
bool InputHandlerManager::IsThreeFingersTapType(std::shared_ptr<PointerEvent> pointerEvent)
{
CHKPF(pointerEvent);
if (pointerEvent->GetSourceType() != PointerEvent::SOURCE_TYPE_TOUCHPAD ||
pointerEvent->GetFingerCount() != THREE_FINGERS ||
(pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_TRIPTAP)) {
return false;
}
return true;
}
#ifdef OHOS_BUILD_ENABLE_FINGERPRINT
bool InputHandlerManager::IsFingerprintType(std::shared_ptr<PointerEvent> pointerEvent)
{
CHKPF(pointerEvent);
if (pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_FINGERPRINT &&
((PointerEvent::POINTER_ACTION_FINGERPRINT_DOWN <= pointerEvent->GetPointerAction() &&
pointerEvent->GetPointerAction() <= PointerEvent::POINTER_ACTION_FINGERPRINT_CLICK) ||
pointerEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_FINGERPRINT_CANCEL ||
pointerEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_FINGERPRINT_HOLD ||
pointerEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_FINGERPRINT_TOUCH)) {
return true;
}
MMI_HILOGD("not fingerprint event");
return false;
}
#endif
bool InputHandlerManager::CheckIfNeedAddToConsumerInfos(const Handler &monitor,
std::shared_ptr<PointerEvent> pointerEvent)
{
CHKPF(pointerEvent);
#ifdef OHOS_BUILD_ENABLE_FINGERPRINT
if ((monitor.eventType_ & HANDLE_EVENT_TYPE_FINGERPRINT) == HANDLE_EVENT_TYPE_FINGERPRINT &&
IsFingerprintType(pointerEvent)) {
return true;
}
#endif
if ((monitor.eventType_ & HANDLE_EVENT_TYPE_POINTER) == HANDLE_EVENT_TYPE_POINTER) {
return true;
} else if ((monitor.eventType_ & HANDLE_EVENT_TYPE_TOUCH_GESTURE) == HANDLE_EVENT_TYPE_TOUCH_GESTURE) {
return true;
} else if ((monitor.eventType_ & HANDLE_EVENT_TYPE_SWIPEINWARD) == HANDLE_EVENT_TYPE_SWIPEINWARD) {
return true;
} else if ((monitor.eventType_ & HANDLE_EVENT_TYPE_TOUCH) == HANDLE_EVENT_TYPE_TOUCH &&
pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
return true;
} else if ((monitor.eventType_ & HANDLE_EVENT_TYPE_MOUSE) == HANDLE_EVENT_TYPE_MOUSE &&
pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_MOUSE) {
return true;
} else if ((monitor.eventType_ & HANDLE_EVENT_TYPE_PINCH) == HANDLE_EVENT_TYPE_PINCH &&
IsPinchType(pointerEvent)) {
return true;
} else if ((monitor.eventType_ & HANDLE_EVENT_TYPE_THREEFINGERSSWIP) == HANDLE_EVENT_TYPE_THREEFINGERSSWIP &&
IsThreeFingersSwipeType(pointerEvent)) {
return true;
} else if ((monitor.eventType_ & HANDLE_EVENT_TYPE_FOURFINGERSSWIP) == HANDLE_EVENT_TYPE_FOURFINGERSSWIP &&
IsFourFingersSwipeType(pointerEvent)) {
return true;
} else if ((monitor.eventType_ & HANDLE_EVENT_TYPE_ROTATE) == HANDLE_EVENT_TYPE_ROTATE &&
IsRotateType(pointerEvent)) {
return true;
} else if ((monitor.eventType_ & HANDLE_EVENT_TYPE_THREEFINGERSTAP) == HANDLE_EVENT_TYPE_THREEFINGERSTAP &&
IsThreeFingersTapType(pointerEvent)) {
return true;
}
return false;
}
int32_t InputHandlerManager::GetMonitorConsumerInfos(std::shared_ptr<PointerEvent> pointerEvent,
std::map<int32_t, std::shared_ptr<IInputEventConsumer>> &consumerInfos)
{
int32_t consumerCount = 0;
CHKPR(pointerEvent, consumerCount);
MMI_HILOG_DISPATCHD("id:%{public}d ac:%{public}d recv", pointerEvent->GetId(), pointerEvent->GetPointerAction());
for (const auto &item : monitorHandlers_) {
if (!CheckIfNeedAddToConsumerInfos(item.second, pointerEvent)) {
continue;
}
if (!IsMatchGesture(item.second, pointerEvent->GetPointerAction(), pointerEvent->GetPointerCount())) {
continue;
}
int32_t handlerId = item.first;
std::shared_ptr<IInputEventConsumer> consumer = item.second.consumer_;
CHKPR(consumer, INVALID_HANDLER_ID);
auto ret = consumerInfos.emplace(handlerId, consumer);
if (!ret.second) {
MMI_HILOGI("Duplicate handler:%{public}d", handlerId);
continue;
}
consumerCount++;
}
for (const auto &item : actionsMonitorHandlers_) {
for (auto action : item.second.actionsType_) {
if (action != pointerEvent->GetPointerAction()) {
continue;
}
int32_t handlerId = item.first;
std::shared_ptr<IInputEventConsumer> consumer = item.second.consumer_;
CHKPR(consumer, INVALID_HANDLER_ID);
auto ret = consumerInfos.emplace(handlerId, consumer);
if (!ret.second) {
MMI_HILOGI("Duplicate handler:%{public}d", handlerId);
continue;
}
consumerCount++;
}
}
return consumerCount;
}
void InputHandlerManager::OnInputEvent(std::shared_ptr<PointerEvent> pointerEvent, uint32_t deviceTags)
{
CHK_PID_AND_TID();
CHKPV(pointerEvent);
BytraceAdapter::StartBytrace(pointerEvent, BytraceAdapter::TRACE_STOP, BytraceAdapter::POINT_INTERCEPT_EVENT);
std::map<int32_t, std::shared_ptr<IInputEventConsumer>> consumerInfos;
GetConsumerInfos(pointerEvent, deviceTags, consumerInfos);
for (auto iter = consumerInfos.begin(); iter != consumerInfos.end(); ++iter) {
auto tempEvent = std::make_shared<PointerEvent>(*pointerEvent);
PointerEvent::PointerItem pointerItem;
tempEvent->GetPointerItem(tempEvent->GetPointerId(), pointerItem);
if (std::next(iter) == consumerInfos.end()) {
tempEvent->SetProcessedCallback(monitorCallbackConsume_);
} else {
tempEvent->SetProcessedCallback(monitorCallback_);
}
if (tempEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_SWIPE_BEGIN ||
tempEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_SWIPE_END) {
MMI_HILOGI("Swipe event sended to handler! action type:%{public}d finger count:%{public}d",
tempEvent->GetPointerAction(),
tempEvent->GetFingerCount());
}
CHKPV(iter->second);
auto consumer = iter->second;
consumer->OnInputEvent(tempEvent);
MMI_HILOG_DISPATCHD("Pointer event id:%{public}d pointerId:%{public}d",
iter->first, pointerEvent->GetPointerId());
}
}
#endif
#if defined(OHOS_BUILD_ENABLE_INTERCEPTOR) || defined(OHOS_BUILD_ENABLE_MONITOR)
template<typename T>
bool InputHandlerManager::RecoverPointerEvent(std::initializer_list<T> pointerActionEvents, T pointerActionEvent)
{
CALL_DEBUG_ENTER;
std::unique_lock lock(mtxHandlers_);
CHKPF(lastPointerEvent_);
int32_t pointerAction = lastPointerEvent_->GetPointerAction();
for (const auto &it : pointerActionEvents) {
if (pointerAction == it) {
PointerEvent::PointerItem item;
int32_t pointerId = lastPointerEvent_->GetPointerId();
if (!lastPointerEvent_->GetPointerItem(pointerId, item)) {
MMI_HILOG_DISPATCHD("Get pointer item failed. pointer:%{public}d",
pointerId);
return false;
}
item.SetPressed(false);
lastPointerEvent_->UpdatePointerItem(pointerId, item);
lastPointerEvent_->SetPointerAction(pointerActionEvent);
auto copiedPointerEvent = std::make_shared<PointerEvent>(*lastPointerEvent_);
lock.unlock();
#if defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)
OnInputEvent(copiedPointerEvent, DEVICE_TAGS);
#endif
return true;
}
}
return false;
}
void InputHandlerManager::OnDisconnected()
{
CALL_DEBUG_ENTER;
std::initializer_list<int32_t> pointerActionSwipeEvents { PointerEvent::POINTER_ACTION_SWIPE_UPDATE,
PointerEvent::POINTER_ACTION_SWIPE_BEGIN };
if (RecoverPointerEvent(pointerActionSwipeEvents, PointerEvent::POINTER_ACTION_SWIPE_END)) {
MMI_HILOGE("Swipe end event for service exception re-sending");
return;
}
}
void InputHandlerManager::OnConnected()
{
std::lock_guard guard(mtxHandlers_);
MMI_HILOGI("Reregister gesture monitors on reconnection");
RegisterGestureMonitors();
MMI_HILOGI("Enable event monitors(interceptors) on reconnection");
HandleEventType eventType = GetEventType();
int32_t priority = GetPriority();
uint32_t deviceTags = GetDeviceTags();
std::vector<int32_t> actionsType = GetActionsType();
if (eventType != HANDLE_EVENT_TYPE_NONE || !actionsType.empty()) {
AddToServer(GetHandlerType(), eventType, priority, deviceTags, actionsType);
}
}
#endif
bool InputHandlerManager::HasHandler(int32_t handlerId)
{
std::lock_guard guard(mtxHandlers_);
bool hasHandler = false;
if (GetHandlerType() == InputHandlerType::MONITOR) {
auto iter = monitorHandlers_.find(handlerId);
hasHandler = (iter != monitorHandlers_.end()) ? true : false;
if (!hasHandler) {
auto iter = actionsMonitorHandlers_.find(handlerId);
return (iter != actionsMonitorHandlers_.end());
}
return hasHandler;
}
if (GetHandlerType() == InputHandlerType::INTERCEPTOR) {
for (const auto &item : interHandlers_) {
if (item.handlerId_ == handlerId) {
return true;
}
}
}
return false;
}
HandleEventType InputHandlerManager::GetEventType() const
{
uint32_t eventType{ HANDLE_EVENT_TYPE_NONE };
if (GetHandlerType() == InputHandlerType::MONITOR) {
if (monitorHandlers_.empty()) {
MMI_HILOGD("The monitorHandlers_ is empty");
return HANDLE_EVENT_TYPE_NONE;
}
for (const auto &inputHandler : monitorHandlers_) {
eventType |= inputHandler.second.eventType_;
}
}
if (GetHandlerType() == InputHandlerType::INTERCEPTOR) {
if (interHandlers_.empty()) {
MMI_HILOGD("The interHandlers_ is empty");
return HANDLE_EVENT_TYPE_NONE;
}
for (const auto &interHandler : interHandlers_) {
eventType |= interHandler.eventType_;
}
}
return eventType;
}
int32_t InputHandlerManager::GetPriority() const
{
int32_t priority{ DEFUALT_INTERCEPTOR_PRIORITY };
if (GetHandlerType() == InputHandlerType::INTERCEPTOR) {
if (!interHandlers_.empty()) {
priority = interHandlers_.front().priority_;
}
}
return priority;
}
uint32_t InputHandlerManager::GetDeviceTags() const
{
uint32_t deviceTags = 0;
if (GetHandlerType() == InputHandlerType::INTERCEPTOR) {
for (const auto &item : interHandlers_) {
deviceTags |= item.deviceTags_;
}
}
if (GetHandlerType() == InputHandlerType::MONITOR) {
for (const auto &item : monitorHandlers_) {
deviceTags |= item.second.deviceTags_;
}
}
return deviceTags;
}
std::vector<int32_t> InputHandlerManager::GetActionsType() const
{
return addToServerActions_;
}
void InputHandlerManager::OnDispatchEventProcessed(int32_t eventId, int64_t actionTime)
{
std::lock_guard guard(mtxHandlers_);
CALL_DEBUG_ENTER;
MMIClientPtr client = MMIEventHdl.GetMMIClient();
CHKPV(client);
if (mouseEventIds_.find(eventId) != mouseEventIds_.end()) {
mouseEventIds_.erase(eventId);
return;
}
}
void InputHandlerManager::OnDispatchEventProcessed(int32_t eventId, int64_t actionTime, bool isNeedConsume)
{
OnDispatchEventProcessed(eventId, actionTime);
ANRHDL->SetLastProcessedEventId(ANR_MONITOR, eventId, actionTime);
}
bool InputHandlerManager::IsMatchGesture(const Handler &handler, int32_t action, int32_t count)
{
if ((handler.eventType_ & HANDLE_EVENT_TYPE_TOUCH_GESTURE) != HANDLE_EVENT_TYPE_TOUCH_GESTURE) {
return true;
}
auto iter = monitorHandlers_.find(handler.handlerId_);
if (iter == monitorHandlers_.end()) {
return false;
}
GestureHandler &gestureHandler = iter->second.gestureHandler_;
TouchGestureType type = TOUCH_GESTURE_TYPE_NONE;
switch (action) {
case PointerEvent::TOUCH_ACTION_SWIPE_DOWN:
case PointerEvent::TOUCH_ACTION_SWIPE_UP:
case PointerEvent::TOUCH_ACTION_SWIPE_RIGHT:
case PointerEvent::TOUCH_ACTION_SWIPE_LEFT:
type = TOUCH_GESTURE_TYPE_SWIPE;
break;
case PointerEvent::TOUCH_ACTION_PINCH_OPENED:
case PointerEvent::TOUCH_ACTION_PINCH_CLOSEED:
type = TOUCH_GESTURE_TYPE_PINCH;
break;
case PointerEvent::TOUCH_ACTION_GESTURE_END: {
if (!gestureHandler.gestureState) {
return false;
}
gestureHandler.gestureState = false;
return true;
}
default: {
MMI_HILOGD("Unknown action:%{public}d", action);
return false;
}
}
if (((gestureHandler.gestureType & type) == type) &&
(gestureHandler.fingers == count || gestureHandler.fingers == ALL_FINGER_COUNT)) {
gestureHandler.gestureState = true;
return true;
}
return false;
}
void InputHandlerManager::RegisterGestureMonitors() const
{
for (const auto &[_, handler] : monitorHandlers_) {
if ((handler.eventType_ & HANDLE_EVENT_TYPE_TOUCH_GESTURE) != HANDLE_EVENT_TYPE_TOUCH_GESTURE) {
continue;
}
MMI_HILOGI("AddGestureMonitor(%{public}u, %{public}d) to server",
handler.gestureHandler_.gestureType, handler.gestureHandler_.fingers);
auto ret = MULTIMODAL_INPUT_CONNECT_MGR->AddGestureMonitor(
InputHandlerType::MONITOR, HANDLE_EVENT_TYPE_TOUCH_GESTURE,
handler.gestureHandler_.gestureType, handler.gestureHandler_.fingers);
if (ret != RET_OK) {
MMI_HILOGE("AddGestureMonitor to server fail, ret:%{public}d", ret);
}
}
}
}
}