diff --git a/adapter/ohos/entrance/ace_view_ohos.cpp b/adapter/ohos/entrance/ace_view_ohos.cpp index 1300b64e247a5d91b7c068737442a0b7d0f8e34f..f1ecffd23535329195bc412969d506dee1c1bbe8 100644 --- a/adapter/ohos/entrance/ace_view_ohos.cpp +++ b/adapter/ohos/entrance/ace_view_ohos.cpp @@ -18,6 +18,7 @@ #include "adapter/ohos/entrance/ace_container.h" #include "adapter/ohos/entrance/mmi_event_convertor.h" #include "base/log/dump_log.h" +#include "core/event/event_info_convertor.h" namespace OHOS::Ace::Platform { namespace { @@ -413,13 +414,45 @@ void AceViewOhos::ProcessMouseEvent(const std::shared_ptr& po markEnabled); }; + if (NG::EventInfoConvertor::IfNeedMouseTransform() && ProcessMouseEventWithTouch(event, node, markProcess)) { + return; + } CHECK_NULL_VOID(mouseEventCallback_); mouseEventCallback_(event, markProcess, node); } +bool AceViewOhos::ProcessMouseEventWithTouch( + const MouseEvent& event, const RefPtr& node, const std::function& markProcess) +{ + if (event.button == MouseButton::LEFT_BUTTON) { + // Only process PRESS/MOVE/RELEASE/CANCEL event + switch (event.action) { + case MouseAction::PRESS: + case MouseAction::RELEASE: + case MouseAction::CANCEL: + case MouseAction::MOVE: + break; + default: + return false; + } + TouchEvent touchEvent = event.CreateTouchPoint(); + touchEvent.SetSourceType(SourceType::TOUCH); + CHECK_NULL_RETURN(touchEventCallback_, false); + touchEventCallback_(touchEvent, markProcess, node); + return true; + } else { + return false; + } +} + void AceViewOhos::ProcessAxisEvent(const std::shared_ptr& pointerEvent, const RefPtr& node, bool isInjected) { + if (NG::EventInfoConvertor::IfNeedMouseTransform()) { + ProcessAxisEventWithTouch(pointerEvent, node, isInjected); + return; + } + CHECK_NULL_VOID(axisEventCallback_); AxisEvent event; event.isInjected = isInjected; @@ -453,6 +486,41 @@ void AceViewOhos::ProcessAxisEvent(const std::shared_ptr& poi axisEventCallback_(event, markProcess, node); } +void AceViewOhos::ProcessAxisEventWithTouch(const std::shared_ptr& pointerEvent, + const RefPtr& node, bool isInjected) +{ + TouchEvent event; + event.isInjected = isInjected; + + if (pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_AXIS_BEGIN || + pointerEvent->GetPointerAction() == OHOS::MMI::PointerEvent::POINTER_ACTION_ROTATE_BEGIN) { + // The first step of axis event of mouse is equivalent to touch event START + UPDATE. + // Create a fake UPDATE event here to adapt to axis event of mouse. + // e.g {START, END} turns into {START, UPDATE, END}. + auto fakeAxisRawEvt = std::make_shared(*pointerEvent); + double axisScrollVertBak = fakeAxisRawEvt->GetAxisValue(MMI::PointerEvent::AxisType::AXIS_TYPE_SCROLL_VERTICAL); + double axisScrollHoriBak = + fakeAxisRawEvt->GetAxisValue(MMI::PointerEvent::AxisType::AXIS_TYPE_SCROLL_HORIZONTAL); + fakeAxisRawEvt->SetAxisValue(MMI::PointerEvent::AxisType::AXIS_TYPE_SCROLL_VERTICAL, 0.0); + fakeAxisRawEvt->SetAxisValue(MMI::PointerEvent::AxisType::AXIS_TYPE_SCROLL_HORIZONTAL, 0.0); + ConvertAxisEventToTouchEvent(fakeAxisRawEvt, event, axisFakePntEvt_); + touchEventCallback_(event, nullptr, node); + fakeAxisRawEvt->SetAxisValue(MMI::PointerEvent::AxisType::AXIS_TYPE_SCROLL_VERTICAL, axisScrollVertBak); + fakeAxisRawEvt->SetAxisValue(MMI::PointerEvent::AxisType::AXIS_TYPE_SCROLL_HORIZONTAL, axisScrollHoriBak); + fakeAxisRawEvt->SetPointerAction(MMI::PointerEvent::POINTER_ACTION_AXIS_UPDATE); + ConvertAxisEventToTouchEvent(fakeAxisRawEvt, event, axisFakePntEvt_); + } else { + ConvertAxisEventToTouchEvent(pointerEvent, event, axisFakePntEvt_); + } + + auto markProcess = [event, enabled = pointerEvent->IsMarkEnabled()]() { + MMI::InputManager::GetInstance()->MarkProcessed(event.touchEventId, + std::chrono::duration_cast(event.time.time_since_epoch()).count(), enabled); + }; + CHECK_NULL_VOID(touchEventCallback_); + touchEventCallback_(event, markProcess, node); +} + bool AceViewOhos::ProcessKeyEvent(const std::shared_ptr& keyEvent, bool isPreIme) { CHECK_NULL_RETURN(nonPointerEventCallback_, false); diff --git a/adapter/ohos/entrance/ace_view_ohos.h b/adapter/ohos/entrance/ace_view_ohos.h index bd647de992d2996b11716f814e815df4871c370a..c03b50791625567b84d8c03974a9e4ec77e31274 100644 --- a/adapter/ohos/entrance/ace_view_ohos.h +++ b/adapter/ohos/entrance/ace_view_ohos.h @@ -235,6 +235,11 @@ private: } } + bool ProcessMouseEventWithTouch(const MouseEvent& event, const RefPtr& node, + const std::function& markProcess); + void ProcessAxisEventWithTouch(const std::shared_ptr& pointerEvent, + const RefPtr& node, bool isInjected); + TouchEventCallback touchEventCallback_; MouseEventCallback mouseEventCallback_; AxisEventCallback axisEventCallback_; @@ -267,6 +272,8 @@ private: std::unique_ptr threadModelImpl_; + OHOS::Ace::PointerEvent axisFakePntEvt_; + ACE_DISALLOW_COPY_AND_MOVE(AceViewOhos); }; } // namespace OHOS::Ace::Platform diff --git a/adapter/ohos/entrance/mmi_event_convertor.cpp b/adapter/ohos/entrance/mmi_event_convertor.cpp index 821b99293f70783e635785da11cf7a8182786fda..ef035967fb2ab4c7faa6e4777adc622fcc31499a 100644 --- a/adapter/ohos/entrance/mmi_event_convertor.cpp +++ b/adapter/ohos/entrance/mmi_event_convertor.cpp @@ -516,6 +516,93 @@ void ConvertAxisEvent(const std::shared_ptr& pointerEvent, Ax } } +static TouchType ConvertRawAxisActionToTouch(int32_t rawAxisAction) +{ + switch (rawAxisAction) { + case OHOS::MMI::PointerEvent::POINTER_ACTION_AXIS_BEGIN: + case OHOS::MMI::PointerEvent::POINTER_ACTION_ROTATE_BEGIN: + return TouchType::DOWN; + case OHOS::MMI::PointerEvent::POINTER_ACTION_AXIS_UPDATE: + case OHOS::MMI::PointerEvent::POINTER_ACTION_ROTATE_UPDATE: + return TouchType::MOVE; + case MMI::PointerEvent::POINTER_ACTION_AXIS_END: + case MMI::PointerEvent::POINTER_ACTION_ROTATE_END: + return TouchType::UP; + case OHOS::MMI::PointerEvent::POINTER_ACTION_CANCEL: + return TouchType::CANCEL; + break; + default: + return TouchType::UNKNOWN; + } +} + +static void ConvertAxisEventToTouchPoint(const std::shared_ptr& pointerEvent, + MMI::PointerEvent::PointerItem& pointerItem, TouchPoint& touchPoint, PointerEvent& axisFakePntEvt) +{ + constexpr float FAKE_TOUCH_PRESSURE = 3.0f; + float cvtStep = SystemProperties::GetScrollCoefficients(); + touchPoint.id = pointerItem.GetPointerId(); + touchPoint.isPressed = !(pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_AXIS_END || + pointerEvent->GetPointerAction() == OHOS::MMI::PointerEvent::POINTER_ACTION_ROTATE_END); + touchPoint.force = FAKE_TOUCH_PRESSURE; + touchPoint.tiltX = 0.0; + touchPoint.tiltY = 0.0; + touchPoint.rollAngle = 0.0; + touchPoint.sourceTool = SourceTool::FINGER; + touchPoint.originalId = pointerItem.GetOriginPointerId(); + touchPoint.width = 0; + touchPoint.height = 0; + touchPoint.size = 0.0; + touchPoint.operatingHand = 0; + + if (pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_AXIS_BEGIN || + pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_ROTATE_BEGIN) { + axisFakePntEvt.time = TimeStamp(std::chrono::microseconds(pointerEvent->GetActionTime())); + touchPoint.x = pointerItem.GetWindowX(); + touchPoint.y = pointerItem.GetWindowY(); + touchPoint.screenX = pointerItem.GetDisplayX(); + touchPoint.screenY = pointerItem.GetDisplayY(); + } else { + const float xOffset = + cvtStep * pointerEvent->GetAxisValue(OHOS::MMI::PointerEvent::AxisType::AXIS_TYPE_SCROLL_HORIZONTAL); + const float yOffset = + cvtStep * pointerEvent->GetAxisValue(OHOS::MMI::PointerEvent::AxisType::AXIS_TYPE_SCROLL_VERTICAL); + touchPoint.x = axisFakePntEvt.x - xOffset; + touchPoint.y = axisFakePntEvt.y - yOffset; + touchPoint.screenX = axisFakePntEvt.screenX - xOffset; + touchPoint.screenY = axisFakePntEvt.screenY - yOffset; + } + axisFakePntEvt.x = touchPoint.x; + axisFakePntEvt.y = touchPoint.y; + axisFakePntEvt.screenX = touchPoint.screenX; + axisFakePntEvt.screenY = touchPoint.screenY; + touchPoint.downTime = axisFakePntEvt.time; +} + +void ConvertAxisEventToTouchEvent(const std::shared_ptr& pointerEvent, TouchEvent& touchEvt, + OHOS::Ace::PointerEvent& axisFakePntEvt) +{ + CHECK_NULL_VOID(pointerEvent); + + int32_t pointerID = pointerEvent->GetPointerId(); + MMI::PointerEvent::PointerItem pointerItem; + if (!pointerEvent->GetPointerItem(pointerID, pointerItem)) { + return; + } + TouchPoint touchPoint; + ConvertAxisEventToTouchPoint(pointerEvent, pointerItem, touchPoint, axisFakePntEvt); + touchEvt = ConvertTouchEventFromTouchPoint(touchPoint); + touchEvt.SetSourceType(SourceType::TOUCH) + .SetType(ConvertRawAxisActionToTouch(pointerEvent->GetPointerAction())) + .SetPullType(TouchType::UNKNOWN) + .SetTime(TimeStamp(std::chrono::microseconds(pointerEvent->GetActionTime()))) + .SetDeviceId(pointerEvent->GetDeviceId()) + .SetTargetDisplayId(pointerEvent->GetTargetDisplayId()) + .SetTouchEventId(pointerEvent->GetId()); + + touchEvt.pointers.emplace_back(std::move(touchPoint)); +} + void ConvertKeyEvent(const std::shared_ptr& keyEvent, KeyEvent& event) { CHECK_NULL_VOID(keyEvent); diff --git a/adapter/ohos/entrance/mmi_event_convertor.h b/adapter/ohos/entrance/mmi_event_convertor.h index 50f8763019a6f0b34a095f00be2724795156f0d7..b1578b53fcbcded0f9a493bbc8b0fb096c654626 100644 --- a/adapter/ohos/entrance/mmi_event_convertor.h +++ b/adapter/ohos/entrance/mmi_event_convertor.h @@ -98,6 +98,9 @@ void ConvertMouseEvent(const std::shared_ptr& pointerEvent, void ConvertAxisEvent(const std::shared_ptr& pointerEvent, AxisEvent& event); +void ConvertAxisEventToTouchEvent(const std::shared_ptr& pointerEvent, TouchEvent& touchEvt, + OHOS::Ace::PointerEvent& axisFakePntEvt_); + void ConvertKeyEvent(const std::shared_ptr& keyEvent, KeyEvent& event); void ConvertFocusAxisEvent(const std::shared_ptr& pointerEvent, NG::FocusAxisEvent& event); diff --git a/adapter/ohos/entrance/ui_content_impl.cpp b/adapter/ohos/entrance/ui_content_impl.cpp index 2e1367ebeb0e652846e6a108437127b9bc8eee8e..c3b7d70c92075575777345c9d5da7dc444d13f96 100644 --- a/adapter/ohos/entrance/ui_content_impl.cpp +++ b/adapter/ohos/entrance/ui_content_impl.cpp @@ -1762,6 +1762,10 @@ void UIContentImpl::StoreConfiguration(const std::shared_ptrGetItem(OHOS::AAFwk::GlobalConfigurationKey::DEVICE_TYPE); + if (!deviceType.empty()) { + SystemProperties::SetConfigDeviceType(deviceType); + } } std::shared_ptr UIContentImpl::GetFormRootNode() diff --git a/adapter/ohos/osal/system_properties.cpp b/adapter/ohos/osal/system_properties.cpp index 120af019ff1c90d784339daee211d9a1b3d4f8a1..9c16de71e52685610999797bde0c610338dd5594 100644 --- a/adapter/ohos/osal/system_properties.cpp +++ b/adapter/ohos/osal/system_properties.cpp @@ -248,6 +248,17 @@ bool IsDebugEnabled() return (system::GetParameter("persist.ace.debug.enabled", "0") == "1"); } +bool IsMouseTransformEnable() +{ + return (system::GetParameter("persist.ace.event.transform.enable", "1") == "1"); +} + +float ReadScrollCoefficients() +{ + auto ret = system::GetParameter("persist.ace.scroll.coefficeient", "2.0"); + return StringUtils::StringToFloat(ret); +} + int64_t GetDebugFlags() { return system::GetIntParameter("persist.ace.debug.flags", 0); @@ -544,6 +555,9 @@ bool SystemProperties::recycleImageEnabled_ = IsRecycleImageEnabled(); bool SystemProperties::debugOffsetLogEnabled_ = IsDebugOffsetLogEnabled(); ACE_WEAK_SYM bool SystemProperties::windowAnimationEnabled_ = IsWindowAnimationEnabled(); ACE_WEAK_SYM bool SystemProperties::debugEnabled_ = IsDebugEnabled(); +std::string SystemProperties::configDeviceType_ = ""; +ACE_WEAK_SYM bool SystemProperties::transformEnabled_ = IsMouseTransformEnable(); +float SystemProperties::scrollCoefficients_ = ReadScrollCoefficients(); ACE_WEAK_SYM DebugFlags SystemProperties::debugFlags_ = GetDebugFlags(); ACE_WEAK_SYM bool SystemProperties::containerDeleteFlag_ = IsContainerDeleteFlag(); ACE_WEAK_SYM bool SystemProperties::layoutDetectEnabled_ = IsLayoutDetectEnabled(); @@ -696,6 +710,7 @@ void SystemProperties::InitDeviceInfo( deviceHeight_ = deviceHeight; needAvoidWindow_ = system::GetBoolParameter(PROPERTY_NEED_AVOID_WINDOW, false); debugEnabled_ = IsDebugEnabled(); + transformEnabled_ = IsMouseTransformEnable(); debugFlags_ = GetDebugFlags(); layoutDetectEnabled_ = IsLayoutDetectEnabled(); svgTraceEnable_ = IsSvgTraceEnabled(); @@ -1109,6 +1124,16 @@ double SystemProperties::GetScrollableDistance() return scrollableDistance_; } +ACE_WEAK_SYM float SystemProperties::GetScrollCoefficients() +{ + return scrollCoefficients_; +} + +ACE_WEAK_SYM bool SystemProperties::GetTransformEnabled() +{ + return transformEnabled_; +} + bool SystemProperties::GetWebDebugMaximizeResizeOptimize() { return system::GetBoolParameter("web.debug.maximize_resize_optimize", true); diff --git a/frameworks/base/utils/system_properties.h b/frameworks/base/utils/system_properties.h index 96076025ca5e5652f3a4c1235ef4609508853246..7a273b3a75cadf67c8a82ef1e03004b91de5133e 100644 --- a/frameworks/base/utils/system_properties.h +++ b/frameworks/base/utils/system_properties.h @@ -490,6 +490,20 @@ public: return isDeviceAccess_; } + static void SetConfigDeviceType(const std::string& type) + { + configDeviceType_ = type; + } + + static const std::string& GetConfigDeviceType() + { + return configDeviceType_; + } + + static float GetScrollCoefficients(); + + static bool GetTransformEnabled(); + static void InitMccMnc(int32_t mcc, int32_t mnc); static ScreenShape GetScreenShape() @@ -741,6 +755,9 @@ private: static bool rosenBackendEnabled_; static bool windowAnimationEnabled_; static bool debugEnabled_; + static std::string configDeviceType_; + static bool transformEnabled_; + static float scrollCoefficients_; static DebugFlags debugFlags_; static bool containerDeleteFlag_; static bool layoutDetectEnabled_; diff --git a/frameworks/core/event/event_info_convertor.cpp b/frameworks/core/event/event_info_convertor.cpp index 306edd9ada9bfcb27a261325b59e0f6c0b0de9be..9f9d1af63f3678ca5d76fe7abac9cf63ec3009b5 100644 --- a/frameworks/core/event/event_info_convertor.cpp +++ b/frameworks/core/event/event_info_convertor.cpp @@ -30,4 +30,9 @@ bool EventInfoConvertor::MatchCompatibleCondition() { return false; } + +bool EventInfoConvertor::IfNeedMouseTransform() +{ + return false; +} } // namespace OHOS::Ace::NG diff --git a/frameworks/core/event/event_info_convertor.h b/frameworks/core/event/event_info_convertor.h index 82320e620f5701915a8a205362bdd3f8aa9dd31f..3d47f2195b4f4506c0f90acd39f990f9f8ad5ff8 100644 --- a/frameworks/core/event/event_info_convertor.h +++ b/frameworks/core/event/event_info_convertor.h @@ -25,6 +25,7 @@ public: static bool ConvertMouseToTouchIfNeeded(const MouseInfo& mouseInfo, TouchEventInfo& touchEventInfo); static bool IsTouchEventNeedAbandoned(const TouchEventInfo& touchEventInfo); static bool MatchCompatibleCondition(); + static bool IfNeedMouseTransform(); private: EventInfoConvertor() = default; ~EventInfoConvertor() = default; diff --git a/test/unittest/core/pattern/window_scene/mock/mock_mmi_event_convertor.cpp b/test/unittest/core/pattern/window_scene/mock/mock_mmi_event_convertor.cpp index e0b493794fea8770985d344777b43419f92c60c3..492a9875c3e71df32731e21ca25fc754de7f2f04 100644 --- a/test/unittest/core/pattern/window_scene/mock/mock_mmi_event_convertor.cpp +++ b/test/unittest/core/pattern/window_scene/mock/mock_mmi_event_convertor.cpp @@ -38,6 +38,10 @@ void ConvertCrownEvent(const std::shared_ptr& pointerEvent, C void ConvertAxisEvent(const std::shared_ptr& pointerEvent, AxisEvent& event) {} +void ConvertAxisEventToTouchEvent( + const std::shared_ptr& pointerEvent, TouchEvent& touchEvt, PointerEvent& axisFakePntEvt_) +{} + void ConvertKeyEvent(const std::shared_ptr& keyEvent, KeyEvent& event) {} void ConvertFocusAxisEvent(const std::shared_ptr& pointerEvent, NG::FocusAxisEvent& event)