1885b47fbSopenharmony_ci/* 2885b47fbSopenharmony_ci * Copyright (C) 2023 Huawei Device Co., Ltd. 3885b47fbSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4885b47fbSopenharmony_ci * you may not use this file except in compliance with the License. 5885b47fbSopenharmony_ci * You may obtain a copy of the License at 6885b47fbSopenharmony_ci * 7885b47fbSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8885b47fbSopenharmony_ci * 9885b47fbSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10885b47fbSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11885b47fbSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12885b47fbSopenharmony_ci * See the License for the specific language governing permissions and 13885b47fbSopenharmony_ci * limitations under the License. 14885b47fbSopenharmony_ci */ 15885b47fbSopenharmony_ci 16885b47fbSopenharmony_ci#include <map> 17885b47fbSopenharmony_ci#include "accessibility_screen_touch.h" 18885b47fbSopenharmony_ci#include "accessibility_circle_drawing_manager.h" 19885b47fbSopenharmony_ci#include "accessible_ability_manager_service.h" 20885b47fbSopenharmony_ci#include "hilog_wrapper.h" 21885b47fbSopenharmony_ci#include "utils.h" 22885b47fbSopenharmony_ci#include "parameters.h" 23885b47fbSopenharmony_ci 24885b47fbSopenharmony_cinamespace OHOS { 25885b47fbSopenharmony_cinamespace Accessibility { 26885b47fbSopenharmony_ci 27885b47fbSopenharmony_ciconstexpr int32_t POINTER_COUNT_1 = 1; 28885b47fbSopenharmony_ci 29885b47fbSopenharmony_ciconstexpr uint32_t CLICK_RESPONSE_DELAY_SHORT = 0; 30885b47fbSopenharmony_ciconstexpr uint32_t CLICK_RESPONSE_DELAY_MEDIUM = 1; 31885b47fbSopenharmony_ciconstexpr uint32_t CLICK_RESPONSE_DELAY_LONG = 2; 32885b47fbSopenharmony_ci 33885b47fbSopenharmony_ciconstexpr uint32_t CLICK_RESPONSE_TIME_SHORT = 0; // ms 34885b47fbSopenharmony_ciconstexpr uint32_t CLICK_RESPONSE_TIME_MEDIUM = 300; // ms 35885b47fbSopenharmony_ciconstexpr uint32_t CLICK_RESPONSE_TIME_LONG = 600; // ms 36885b47fbSopenharmony_ci 37885b47fbSopenharmony_ciconstexpr uint32_t IGNORE_REPEAT_CLICK_SHORTEST = 0; 38885b47fbSopenharmony_ciconstexpr uint32_t IGNORE_REPEAT_CLICK_SHORT = 1; 39885b47fbSopenharmony_ciconstexpr uint32_t IGNORE_REPEAT_CLICK_MEDIUM = 2; 40885b47fbSopenharmony_ciconstexpr uint32_t IGNORE_REPEAT_CLICK_LONG = 3; 41885b47fbSopenharmony_ciconstexpr uint32_t IGNORE_REPEAT_CLICK_LONGEST = 4; 42885b47fbSopenharmony_ci 43885b47fbSopenharmony_ciconstexpr uint32_t IGNORE_REPEAT_CLICK_TIME_SHORTEST = 100; // ms 44885b47fbSopenharmony_ciconstexpr uint32_t IGNORE_REPEAT_CLICK_TIME_SHORT = 400; // ms 45885b47fbSopenharmony_ciconstexpr uint32_t IGNORE_REPEAT_CLICK_TIME_MEDIUM = 700; // ms 46885b47fbSopenharmony_ciconstexpr uint32_t IGNORE_REPEAT_CLICK_TIME_LONG = 1000; // ms 47885b47fbSopenharmony_ciconstexpr uint32_t IGNORE_REPEAT_CLICK_TIME_LONGEST = 1300; // ms 48885b47fbSopenharmony_ci 49885b47fbSopenharmony_ciconstexpr uint32_t CIRCLE_ANGLE = 360; 50885b47fbSopenharmony_ci#ifdef OHOS_BUILD_ENABLE_DISPLAY_MANAGER 51885b47fbSopenharmony_ciconstexpr uint32_t START_ANGLE_PORTRAIT = -90; 52885b47fbSopenharmony_ciconstexpr uint32_t START_ANGLE_LANDSCAPE = 180; 53885b47fbSopenharmony_ciconstexpr uint32_t START_ANGLE_PORTRAIT_INVERTED = 90; 54885b47fbSopenharmony_ciconstexpr uint32_t START_ANGLE_LANDSCAPE_INVERTED = 0; 55885b47fbSopenharmony_ci#endif 56885b47fbSopenharmony_ciconstexpr uint32_t NUMBER_10 = 10; 57885b47fbSopenharmony_ci 58885b47fbSopenharmony_ciconstexpr float TOUCH_SLOP = 8.0f; 59885b47fbSopenharmony_ci 60885b47fbSopenharmony_ciconst int32_t ROTATE_POLICY = system::GetIntParameter("const.window.device.rotate_policy", 0); 61885b47fbSopenharmony_ciconst std::string FOLDABLE = system::GetParameter("const.window.foldabledevice.rotate_policy", ""); 62885b47fbSopenharmony_ciconstexpr int32_t WINDOW_ROTATE = 0; 63885b47fbSopenharmony_ciconstexpr int32_t SCREEN_ROTATE = 1; 64885b47fbSopenharmony_ciconstexpr int32_t FOLDABLE_DEVICE = 2; 65885b47fbSopenharmony_ciconstexpr int32_t SUBSCRIPT_TWO = 2; 66885b47fbSopenharmony_ciconstexpr int32_t SUBSCRIPT_ZERO = 0; 67885b47fbSopenharmony_ciconstexpr char FOLDABLE_SCREEN_ROTATE = '1'; 68885b47fbSopenharmony_ci 69885b47fbSopenharmony_ciconst std::map<uint32_t, uint32_t> CLICK_RESPONSE_TIME_MAP = { 70885b47fbSopenharmony_ci {CLICK_RESPONSE_DELAY_SHORT, CLICK_RESPONSE_TIME_SHORT}, 71885b47fbSopenharmony_ci {CLICK_RESPONSE_DELAY_MEDIUM, CLICK_RESPONSE_TIME_MEDIUM}, 72885b47fbSopenharmony_ci {CLICK_RESPONSE_DELAY_LONG, CLICK_RESPONSE_TIME_LONG} 73885b47fbSopenharmony_ci}; 74885b47fbSopenharmony_ci 75885b47fbSopenharmony_ciconst std::map<uint32_t, uint32_t> IGNORE_REPEAT_CLICK_TIME_MAP = { 76885b47fbSopenharmony_ci {IGNORE_REPEAT_CLICK_SHORTEST, IGNORE_REPEAT_CLICK_TIME_SHORTEST}, 77885b47fbSopenharmony_ci {IGNORE_REPEAT_CLICK_SHORT, IGNORE_REPEAT_CLICK_TIME_SHORT}, 78885b47fbSopenharmony_ci {IGNORE_REPEAT_CLICK_MEDIUM, IGNORE_REPEAT_CLICK_TIME_MEDIUM}, 79885b47fbSopenharmony_ci {IGNORE_REPEAT_CLICK_LONG, IGNORE_REPEAT_CLICK_TIME_LONG}, 80885b47fbSopenharmony_ci {IGNORE_REPEAT_CLICK_LONGEST, IGNORE_REPEAT_CLICK_TIME_LONGEST} 81885b47fbSopenharmony_ci}; 82885b47fbSopenharmony_ci 83885b47fbSopenharmony_ciint64_t AccessibilityScreenTouch::lastUpTime = 0; // global last up time 84885b47fbSopenharmony_ci 85885b47fbSopenharmony_ciScreenTouchHandler::ScreenTouchHandler(const std::shared_ptr<AppExecFwk::EventRunner> &runner, 86885b47fbSopenharmony_ci AccessibilityScreenTouch &server) : AppExecFwk::EventHandler(runner), server_(server) 87885b47fbSopenharmony_ci{ 88885b47fbSopenharmony_ci} 89885b47fbSopenharmony_ci 90885b47fbSopenharmony_ciAccessibilityScreenTouch::AccessibilityScreenTouch() 91885b47fbSopenharmony_ci{ 92885b47fbSopenharmony_ci HILOG_DEBUG(); 93885b47fbSopenharmony_ci // get from account data directly 94885b47fbSopenharmony_ci sptr<AccessibilityAccountData> accountData = 95885b47fbSopenharmony_ci Singleton<AccessibleAbilityManagerService>::GetInstance().GetCurrentAccountData(); 96885b47fbSopenharmony_ci clickResponseTime_ = accountData->GetConfig()->GetClickResponseTime(); 97885b47fbSopenharmony_ci ignoreRepeatClickState_ = accountData->GetConfig()->GetIgnoreRepeatClickState(); 98885b47fbSopenharmony_ci ignoreRepeatClickTime_ = accountData->GetConfig()->GetIgnoreRepeatClickTime(); 99885b47fbSopenharmony_ci 100885b47fbSopenharmony_ci if (clickResponseTime_ > 0 && ignoreRepeatClickState_ == true) { 101885b47fbSopenharmony_ci currentState_ = BOTH_RESPONSE_DELAY_IGNORE_REPEAT_CLICK; 102885b47fbSopenharmony_ci } else if (clickResponseTime_ > 0) { 103885b47fbSopenharmony_ci currentState_ = CLICK_RESPONSE_DELAY_STATE; 104885b47fbSopenharmony_ci } else if (ignoreRepeatClickState_ == true) { 105885b47fbSopenharmony_ci currentState_ = IGNORE_REPEAT_CLICK_STATE; 106885b47fbSopenharmony_ci } else { 107885b47fbSopenharmony_ci currentState_ = DEFAULT_STATE; 108885b47fbSopenharmony_ci } 109885b47fbSopenharmony_ci 110885b47fbSopenharmony_ci lastUpTime_ = lastUpTime; 111885b47fbSopenharmony_ci 112885b47fbSopenharmony_ci runner_ = Singleton<AccessibleAbilityManagerService>::GetInstance().GetMainRunner(); 113885b47fbSopenharmony_ci if (!runner_) { 114885b47fbSopenharmony_ci HILOG_ERROR("get runner failed"); 115885b47fbSopenharmony_ci return; 116885b47fbSopenharmony_ci } 117885b47fbSopenharmony_ci handler_ = std::make_shared<ScreenTouchHandler>(runner_, *this); 118885b47fbSopenharmony_ci if (!handler_) { 119885b47fbSopenharmony_ci HILOG_ERROR("create event handler failed"); 120885b47fbSopenharmony_ci return; 121885b47fbSopenharmony_ci } 122885b47fbSopenharmony_ci} 123885b47fbSopenharmony_ci 124885b47fbSopenharmony_civoid ScreenTouchHandler::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event) 125885b47fbSopenharmony_ci{ 126885b47fbSopenharmony_ci HILOG_DEBUG(); 127885b47fbSopenharmony_ci switch (event->GetInnerEventId()) { 128885b47fbSopenharmony_ci case AccessibilityScreenTouch::FINGER_DOWN_DELAY_MSG: 129885b47fbSopenharmony_ci server_.SendInterceptedEvent(); 130885b47fbSopenharmony_ci break; 131885b47fbSopenharmony_ci default: 132885b47fbSopenharmony_ci break; 133885b47fbSopenharmony_ci } 134885b47fbSopenharmony_ci} 135885b47fbSopenharmony_ci 136885b47fbSopenharmony_ciAccessibilityScreenTouch::~AccessibilityScreenTouch() 137885b47fbSopenharmony_ci{ 138885b47fbSopenharmony_ci lastUpTime = lastUpTime_; 139885b47fbSopenharmony_ci if (drawCircleThread_ && drawCircleThread_->joinable()) { 140885b47fbSopenharmony_ci drawCircleThread_->join(); 141885b47fbSopenharmony_ci } 142885b47fbSopenharmony_ci drawCircleThread_ = nullptr; 143885b47fbSopenharmony_ci AccessibilityCircleDrawingManager::DeleteInstance(); 144885b47fbSopenharmony_ci} 145885b47fbSopenharmony_ci 146885b47fbSopenharmony_civoid AccessibilityScreenTouch::SendInterceptedEvent() 147885b47fbSopenharmony_ci{ 148885b47fbSopenharmony_ci HILOG_DEBUG(); 149885b47fbSopenharmony_ci isStopDrawCircle_ = true; 150885b47fbSopenharmony_ci 151885b47fbSopenharmony_ci if (cachedDownPointerEvents_.empty()) { 152885b47fbSopenharmony_ci HILOG_ERROR("Cached down pointer event is empty!"); 153885b47fbSopenharmony_ci return; 154885b47fbSopenharmony_ci } 155885b47fbSopenharmony_ci 156885b47fbSopenharmony_ci for (auto iter = cachedDownPointerEvents_.begin(); iter != cachedDownPointerEvents_.end(); ++iter) { 157885b47fbSopenharmony_ci iter->SetActionTime(Utils::GetSystemTime() * US_TO_MS); 158885b47fbSopenharmony_ci EventTransmission::OnPointerEvent(*iter); 159885b47fbSopenharmony_ci } 160885b47fbSopenharmony_ci} 161885b47fbSopenharmony_ci 162885b47fbSopenharmony_ciuint32_t AccessibilityScreenTouch::GetRealClickResponseTime() 163885b47fbSopenharmony_ci{ 164885b47fbSopenharmony_ci auto iter = CLICK_RESPONSE_TIME_MAP.find(clickResponseTime_); 165885b47fbSopenharmony_ci if (iter != CLICK_RESPONSE_TIME_MAP.end()) { 166885b47fbSopenharmony_ci return iter->second; 167885b47fbSopenharmony_ci } 168885b47fbSopenharmony_ci 169885b47fbSopenharmony_ci return CLICK_RESPONSE_TIME_MAP.at(CLICK_RESPONSE_DELAY_SHORT); 170885b47fbSopenharmony_ci} 171885b47fbSopenharmony_ci 172885b47fbSopenharmony_ciuint32_t AccessibilityScreenTouch::GetRealIgnoreRepeatClickTime() 173885b47fbSopenharmony_ci{ 174885b47fbSopenharmony_ci auto iter = IGNORE_REPEAT_CLICK_TIME_MAP.find(ignoreRepeatClickTime_); 175885b47fbSopenharmony_ci if (iter != IGNORE_REPEAT_CLICK_TIME_MAP.end()) { 176885b47fbSopenharmony_ci return iter->second; 177885b47fbSopenharmony_ci } 178885b47fbSopenharmony_ci 179885b47fbSopenharmony_ci return IGNORE_REPEAT_CLICK_TIME_MAP.at(IGNORE_REPEAT_CLICK_SHORTEST); 180885b47fbSopenharmony_ci} 181885b47fbSopenharmony_ci 182885b47fbSopenharmony_cibool AccessibilityScreenTouch::GetRealIgnoreRepeatClickState() 183885b47fbSopenharmony_ci{ 184885b47fbSopenharmony_ci return ignoreRepeatClickState_; 185885b47fbSopenharmony_ci} 186885b47fbSopenharmony_ci 187885b47fbSopenharmony_civoid AccessibilityScreenTouch::ConversionCoordinates(int32_t originalX, int32_t originalY) 188885b47fbSopenharmony_ci{ 189885b47fbSopenharmony_ci#ifdef OHOS_BUILD_ENABLE_DISPLAY_MANAGER 190885b47fbSopenharmony_ci AccessibilityDisplayManager &displayMgr = Singleton<AccessibilityDisplayManager>::GetInstance(); 191885b47fbSopenharmony_ci int32_t displayWidth = displayMgr.GetWidth(); 192885b47fbSopenharmony_ci int32_t displayHeight = displayMgr.GetHeight(); 193885b47fbSopenharmony_ci 194885b47fbSopenharmony_ci OHOS::Rosen::DisplayOrientation orientation = displayMgr.GetOrientation(); 195885b47fbSopenharmony_ci switch (orientation) { 196885b47fbSopenharmony_ci case OHOS::Rosen::DisplayOrientation::PORTRAIT: 197885b47fbSopenharmony_ci circleCenterPhysicalX_ = originalX; 198885b47fbSopenharmony_ci circleCenterPhysicalY_ = originalY; 199885b47fbSopenharmony_ci startAngle_ = START_ANGLE_PORTRAIT; 200885b47fbSopenharmony_ci break; 201885b47fbSopenharmony_ci case OHOS::Rosen::DisplayOrientation::LANDSCAPE: 202885b47fbSopenharmony_ci circleCenterPhysicalX_ = originalY; 203885b47fbSopenharmony_ci circleCenterPhysicalY_ = displayWidth - originalX; 204885b47fbSopenharmony_ci startAngle_ = START_ANGLE_LANDSCAPE; 205885b47fbSopenharmony_ci break; 206885b47fbSopenharmony_ci case OHOS::Rosen::DisplayOrientation::PORTRAIT_INVERTED: 207885b47fbSopenharmony_ci circleCenterPhysicalX_ = displayWidth - originalX; 208885b47fbSopenharmony_ci circleCenterPhysicalY_ = displayHeight - originalY; 209885b47fbSopenharmony_ci startAngle_ = START_ANGLE_PORTRAIT_INVERTED; 210885b47fbSopenharmony_ci break; 211885b47fbSopenharmony_ci case OHOS::Rosen::DisplayOrientation::LANDSCAPE_INVERTED: 212885b47fbSopenharmony_ci circleCenterPhysicalX_ = displayHeight - originalY; 213885b47fbSopenharmony_ci circleCenterPhysicalY_ = originalX; 214885b47fbSopenharmony_ci startAngle_ = START_ANGLE_LANDSCAPE_INVERTED; 215885b47fbSopenharmony_ci break; 216885b47fbSopenharmony_ci default: 217885b47fbSopenharmony_ci break; 218885b47fbSopenharmony_ci } 219885b47fbSopenharmony_ci#endif 220885b47fbSopenharmony_ci} 221885b47fbSopenharmony_ci 222885b47fbSopenharmony_civoid AccessibilityScreenTouch::HandleCoordinates(MMI::PointerEvent::PointerItem &pointerItem) 223885b47fbSopenharmony_ci{ 224885b47fbSopenharmony_ci#ifdef OHOS_BUILD_ENABLE_DISPLAY_MANAGER 225885b47fbSopenharmony_ci AccessibilityDisplayManager &displayMgr = Singleton<AccessibilityDisplayManager>::GetInstance(); 226885b47fbSopenharmony_ci int32_t originalX = pointerItem.GetDisplayX(); 227885b47fbSopenharmony_ci int32_t originalY = pointerItem.GetDisplayY(); 228885b47fbSopenharmony_ci 229885b47fbSopenharmony_ci switch (ROTATE_POLICY) { 230885b47fbSopenharmony_ci case WINDOW_ROTATE: 231885b47fbSopenharmony_ci ConversionCoordinates(originalX, originalY); 232885b47fbSopenharmony_ci break; 233885b47fbSopenharmony_ci case SCREEN_ROTATE: 234885b47fbSopenharmony_ci circleCenterPhysicalX_ = originalX; 235885b47fbSopenharmony_ci circleCenterPhysicalY_ = originalY; 236885b47fbSopenharmony_ci startAngle_ = START_ANGLE_PORTRAIT; 237885b47fbSopenharmony_ci break; 238885b47fbSopenharmony_ci case FOLDABLE_DEVICE: 239885b47fbSopenharmony_ci if ((displayMgr.GetFoldStatus() == Rosen::FoldStatus::EXPAND && 240885b47fbSopenharmony_ci FOLDABLE[SUBSCRIPT_TWO] == FOLDABLE_SCREEN_ROTATE) || 241885b47fbSopenharmony_ci (displayMgr.GetFoldStatus() == Rosen::FoldStatus::FOLDED && 242885b47fbSopenharmony_ci FOLDABLE[SUBSCRIPT_ZERO] == FOLDABLE_SCREEN_ROTATE)) { 243885b47fbSopenharmony_ci circleCenterPhysicalX_ = originalX; 244885b47fbSopenharmony_ci circleCenterPhysicalY_ = originalY; 245885b47fbSopenharmony_ci startAngle_ = START_ANGLE_PORTRAIT; 246885b47fbSopenharmony_ci } else { 247885b47fbSopenharmony_ci ConversionCoordinates(originalX, originalY); 248885b47fbSopenharmony_ci } 249885b47fbSopenharmony_ci break; 250885b47fbSopenharmony_ci default: 251885b47fbSopenharmony_ci HILOG_WARN("unknown rotate policy"); 252885b47fbSopenharmony_ci ConversionCoordinates(originalX, originalY); 253885b47fbSopenharmony_ci break; 254885b47fbSopenharmony_ci } 255885b47fbSopenharmony_ci#endif 256885b47fbSopenharmony_ci} 257885b47fbSopenharmony_ci 258885b47fbSopenharmony_civoid AccessibilityScreenTouch::DrawCircleProgress() 259885b47fbSopenharmony_ci{ 260885b47fbSopenharmony_ci HILOG_DEBUG(); 261885b47fbSopenharmony_ci 262885b47fbSopenharmony_ci AccessibilityCircleDrawingManager::GetInstance()->DrawPointer(circleCenterPhysicalX_, 263885b47fbSopenharmony_ci circleCenterPhysicalY_, 0, screenId_, startAngle_); 264885b47fbSopenharmony_ci AccessibilityCircleDrawingManager::GetInstance()->UpdatePointerVisible(true); 265885b47fbSopenharmony_ci uint32_t times = GetRealClickResponseTime() / NUMBER_10; 266885b47fbSopenharmony_ci uint32_t step = CIRCLE_ANGLE / times; 267885b47fbSopenharmony_ci uint32_t time = 0; 268885b47fbSopenharmony_ci while (time < times && isStopDrawCircle_ == false) { 269885b47fbSopenharmony_ci AccessibilityCircleDrawingManager::GetInstance()->DrawPointer(circleCenterPhysicalX_, 270885b47fbSopenharmony_ci circleCenterPhysicalY_, step * time, screenId_, startAngle_); 271885b47fbSopenharmony_ci time++; 272885b47fbSopenharmony_ci std::this_thread::yield(); 273885b47fbSopenharmony_ci std::this_thread::sleep_for(std::chrono::milliseconds(NUMBER_10)); 274885b47fbSopenharmony_ci } 275885b47fbSopenharmony_ci 276885b47fbSopenharmony_ci AccessibilityCircleDrawingManager::GetInstance()->UpdatePointerVisible(false); 277885b47fbSopenharmony_ci} 278885b47fbSopenharmony_ci 279885b47fbSopenharmony_civoid AccessibilityScreenTouch::HandleResponseDelayStateInnerDown(MMI::PointerEvent &event) 280885b47fbSopenharmony_ci{ 281885b47fbSopenharmony_ci HILOG_DEBUG(); 282885b47fbSopenharmony_ci MMI::PointerEvent::PointerItem pointerItem; 283885b47fbSopenharmony_ci if (!event.GetPointerItem(event.GetPointerId(), pointerItem)) { 284885b47fbSopenharmony_ci HILOG_WARN("get GetPointerItem %{public}d failed", event.GetPointerId()); 285885b47fbSopenharmony_ci } 286885b47fbSopenharmony_ci 287885b47fbSopenharmony_ci if (event.GetPointerIds().size() > POINTER_COUNT_1) { 288885b47fbSopenharmony_ci if (cachedDownPointerEvents_.empty()) { 289885b47fbSopenharmony_ci HILOG_ERROR("cached down pointer event is empty!"); 290885b47fbSopenharmony_ci return; 291885b47fbSopenharmony_ci } 292885b47fbSopenharmony_ci if (isMoveBeyondThreshold_ == true) { 293885b47fbSopenharmony_ci cachedDownPointerEvents_.push_back(event); 294885b47fbSopenharmony_ci EventTransmission::OnPointerEvent(event); 295885b47fbSopenharmony_ci return; 296885b47fbSopenharmony_ci } else if (isStopDrawCircle_ == true) { 297885b47fbSopenharmony_ci return; 298885b47fbSopenharmony_ci } else { 299885b47fbSopenharmony_ci cachedDownPointerEvents_.push_back(event); 300885b47fbSopenharmony_ci return; 301885b47fbSopenharmony_ci } 302885b47fbSopenharmony_ci } 303885b47fbSopenharmony_ci 304885b47fbSopenharmony_ci screenId_ = event.GetTargetDisplayId(); 305885b47fbSopenharmony_ci startTime_ = event.GetActionTime(); 306885b47fbSopenharmony_ci startPointer_ = std::make_shared<MMI::PointerEvent::PointerItem>(pointerItem); 307885b47fbSopenharmony_ci isMoveBeyondThreshold_ = false; 308885b47fbSopenharmony_ci 309885b47fbSopenharmony_ci HILOG_INFO("ROTATE_POLICY = %{public}d, FOLDABLE = %{public}s", ROTATE_POLICY, FOLDABLE.c_str()); 310885b47fbSopenharmony_ci HandleCoordinates(pointerItem); 311885b47fbSopenharmony_ci isStopDrawCircle_ = false; 312885b47fbSopenharmony_ci if (drawCircleThread_ && drawCircleThread_->joinable()) { 313885b47fbSopenharmony_ci drawCircleThread_->join(); 314885b47fbSopenharmony_ci } 315885b47fbSopenharmony_ci 316885b47fbSopenharmony_ci drawCircleThread_ = nullptr; 317885b47fbSopenharmony_ci drawCircleThread_ = std::make_shared<std::thread>([this] {this->DrawCircleProgress();}); 318885b47fbSopenharmony_ci if (drawCircleThread_ == nullptr) { 319885b47fbSopenharmony_ci HILOG_ERROR("create draw circle progress fail"); 320885b47fbSopenharmony_ci } 321885b47fbSopenharmony_ci 322885b47fbSopenharmony_ci handler_->RemoveEvent(FINGER_DOWN_DELAY_MSG); 323885b47fbSopenharmony_ci cachedDownPointerEvents_.clear(); 324885b47fbSopenharmony_ci cachedDownPointerEvents_.push_back(event); 325885b47fbSopenharmony_ci handler_->SendEvent(FINGER_DOWN_DELAY_MSG, 0, static_cast<int32_t>(GetRealClickResponseTime())); 326885b47fbSopenharmony_ci} 327885b47fbSopenharmony_ci 328885b47fbSopenharmony_civoid AccessibilityScreenTouch::HandleResponseDelayStateInnerMove(MMI::PointerEvent &event) 329885b47fbSopenharmony_ci{ 330885b47fbSopenharmony_ci HILOG_DEBUG(); 331885b47fbSopenharmony_ci if (cachedDownPointerEvents_.empty()) { 332885b47fbSopenharmony_ci HILOG_ERROR("cached down pointer event is empty!"); 333885b47fbSopenharmony_ci return; 334885b47fbSopenharmony_ci } 335885b47fbSopenharmony_ci 336885b47fbSopenharmony_ci if (isMoveBeyondThreshold_ == true) { 337885b47fbSopenharmony_ci handler_->RemoveEvent(FINGER_DOWN_DELAY_MSG); 338885b47fbSopenharmony_ci EventTransmission::OnPointerEvent(event); 339885b47fbSopenharmony_ci return; 340885b47fbSopenharmony_ci } 341885b47fbSopenharmony_ci 342885b47fbSopenharmony_ci if (startPointer_ == nullptr) { 343885b47fbSopenharmony_ci return; 344885b47fbSopenharmony_ci } 345885b47fbSopenharmony_ci 346885b47fbSopenharmony_ci if (event.GetPointerId() != startPointer_->GetPointerId()) { 347885b47fbSopenharmony_ci if (isStopDrawCircle_ == true) { 348885b47fbSopenharmony_ci EventTransmission::OnPointerEvent(event); 349885b47fbSopenharmony_ci } 350885b47fbSopenharmony_ci return; 351885b47fbSopenharmony_ci } 352885b47fbSopenharmony_ci 353885b47fbSopenharmony_ci MMI::PointerEvent::PointerItem pointerItem; 354885b47fbSopenharmony_ci if (!event.GetPointerItem(event.GetPointerId(), pointerItem)) { 355885b47fbSopenharmony_ci HILOG_WARN("get GetPointerItem %{public}d failed", event.GetPointerId()); 356885b47fbSopenharmony_ci } 357885b47fbSopenharmony_ci 358885b47fbSopenharmony_ci float offsetX = startPointer_->GetDisplayX() - pointerItem.GetDisplayX(); 359885b47fbSopenharmony_ci float offsetY = startPointer_->GetDisplayY() - pointerItem.GetDisplayY(); 360885b47fbSopenharmony_ci double duration = hypot(offsetX, offsetY); 361885b47fbSopenharmony_ci if (duration > TOUCH_SLOP) { 362885b47fbSopenharmony_ci handler_->RemoveEvent(FINGER_DOWN_DELAY_MSG); 363885b47fbSopenharmony_ci if (isStopDrawCircle_ != true && !cachedDownPointerEvents_.empty()) { 364885b47fbSopenharmony_ci for (auto iter = cachedDownPointerEvents_.begin(); iter != cachedDownPointerEvents_.end(); ++iter) { 365885b47fbSopenharmony_ci iter->SetActionTime(Utils::GetSystemTime() * US_TO_MS); 366885b47fbSopenharmony_ci EventTransmission::OnPointerEvent(*iter); 367885b47fbSopenharmony_ci } 368885b47fbSopenharmony_ci } 369885b47fbSopenharmony_ci EventTransmission::OnPointerEvent(event); 370885b47fbSopenharmony_ci isMoveBeyondThreshold_ = true; 371885b47fbSopenharmony_ci isStopDrawCircle_ = true; 372885b47fbSopenharmony_ci return; 373885b47fbSopenharmony_ci } 374885b47fbSopenharmony_ci 375885b47fbSopenharmony_ci if (isStopDrawCircle_ != true) { 376885b47fbSopenharmony_ci HandleCoordinates(pointerItem); 377885b47fbSopenharmony_ci return; 378885b47fbSopenharmony_ci } 379885b47fbSopenharmony_ci 380885b47fbSopenharmony_ci EventTransmission::OnPointerEvent(event); 381885b47fbSopenharmony_ci} 382885b47fbSopenharmony_ci 383885b47fbSopenharmony_civoid AccessibilityScreenTouch::HandleResponseDelayStateInnerUp(MMI::PointerEvent &event) 384885b47fbSopenharmony_ci{ 385885b47fbSopenharmony_ci HILOG_DEBUG(); 386885b47fbSopenharmony_ci 387885b47fbSopenharmony_ci if (cachedDownPointerEvents_.empty()) { 388885b47fbSopenharmony_ci HILOG_ERROR("cached down pointer event is empty!"); 389885b47fbSopenharmony_ci handler_->RemoveEvent(FINGER_DOWN_DELAY_MSG); 390885b47fbSopenharmony_ci isStopDrawCircle_ = true; 391885b47fbSopenharmony_ci return; 392885b47fbSopenharmony_ci } 393885b47fbSopenharmony_ci 394885b47fbSopenharmony_ci if (isStopDrawCircle_ == true) { 395885b47fbSopenharmony_ci for (auto iter = cachedDownPointerEvents_.begin(); iter != cachedDownPointerEvents_.end(); ++iter) { 396885b47fbSopenharmony_ci if (iter->GetPointerId() == event.GetPointerId()) { 397885b47fbSopenharmony_ci EventTransmission::OnPointerEvent(event); 398885b47fbSopenharmony_ci } 399885b47fbSopenharmony_ci } 400885b47fbSopenharmony_ci if (event.GetPointerIds().size() == POINTER_COUNT_1) { 401885b47fbSopenharmony_ci cachedDownPointerEvents_.clear(); 402885b47fbSopenharmony_ci } 403885b47fbSopenharmony_ci return; 404885b47fbSopenharmony_ci } 405885b47fbSopenharmony_ci 406885b47fbSopenharmony_ci if (startPointer_ != nullptr && event.GetPointerId() == startPointer_->GetPointerId()) { 407885b47fbSopenharmony_ci handler_->RemoveEvent(FINGER_DOWN_DELAY_MSG); 408885b47fbSopenharmony_ci isStopDrawCircle_ = true; 409885b47fbSopenharmony_ci cachedDownPointerEvents_.clear(); 410885b47fbSopenharmony_ci } else { 411885b47fbSopenharmony_ci auto iter = std::find_if(cachedDownPointerEvents_.begin(), cachedDownPointerEvents_.end(), 412885b47fbSopenharmony_ci [&](const MMI::PointerEvent &e) { 413885b47fbSopenharmony_ci return e.GetPointerId() == event.GetPointerId(); 414885b47fbSopenharmony_ci }); 415885b47fbSopenharmony_ci if (iter != cachedDownPointerEvents_.end()) { 416885b47fbSopenharmony_ci cachedDownPointerEvents_.erase(iter); 417885b47fbSopenharmony_ci } 418885b47fbSopenharmony_ci } 419885b47fbSopenharmony_ci} 420885b47fbSopenharmony_ci 421885b47fbSopenharmony_civoid AccessibilityScreenTouch::HandleResponseDelayState(MMI::PointerEvent &event) 422885b47fbSopenharmony_ci{ 423885b47fbSopenharmony_ci HILOG_DEBUG(); 424885b47fbSopenharmony_ci 425885b47fbSopenharmony_ci switch (event.GetPointerAction()) { 426885b47fbSopenharmony_ci case MMI::PointerEvent::POINTER_ACTION_DOWN: 427885b47fbSopenharmony_ci HandleResponseDelayStateInnerDown(event); 428885b47fbSopenharmony_ci break; 429885b47fbSopenharmony_ci case MMI::PointerEvent::POINTER_ACTION_MOVE: 430885b47fbSopenharmony_ci HandleResponseDelayStateInnerMove(event); 431885b47fbSopenharmony_ci break; 432885b47fbSopenharmony_ci case MMI::PointerEvent::POINTER_ACTION_UP: 433885b47fbSopenharmony_ci HandleResponseDelayStateInnerUp(event); 434885b47fbSopenharmony_ci break; 435885b47fbSopenharmony_ci default: 436885b47fbSopenharmony_ci EventTransmission::OnPointerEvent(event); 437885b47fbSopenharmony_ci break; 438885b47fbSopenharmony_ci } 439885b47fbSopenharmony_ci} 440885b47fbSopenharmony_ci 441885b47fbSopenharmony_civoid AccessibilityScreenTouch::HandleIgnoreRepeatClickStateInnerDown(MMI::PointerEvent &event) 442885b47fbSopenharmony_ci{ 443885b47fbSopenharmony_ci HILOG_DEBUG(); 444885b47fbSopenharmony_ci 445885b47fbSopenharmony_ci int64_t downTime = event.GetActionTime(); 446885b47fbSopenharmony_ci if ((event.GetPointerIds().size() == POINTER_COUNT_1) && 447885b47fbSopenharmony_ci ((downTime - lastUpTime_) / US_TO_MS < GetRealIgnoreRepeatClickTime())) { 448885b47fbSopenharmony_ci isInterceptClick_ = true; 449885b47fbSopenharmony_ci return; 450885b47fbSopenharmony_ci } else if ((event.GetPointerIds().size() > POINTER_COUNT_1) && (isInterceptClick_ == true)) { 451885b47fbSopenharmony_ci return; 452885b47fbSopenharmony_ci } 453885b47fbSopenharmony_ci 454885b47fbSopenharmony_ci EventTransmission::OnPointerEvent(event); 455885b47fbSopenharmony_ci isInterceptClick_ = false; 456885b47fbSopenharmony_ci} 457885b47fbSopenharmony_ci 458885b47fbSopenharmony_civoid AccessibilityScreenTouch::HandleIgnoreRepeatClickStateInnerMove(MMI::PointerEvent &event) 459885b47fbSopenharmony_ci{ 460885b47fbSopenharmony_ci HILOG_DEBUG(); 461885b47fbSopenharmony_ci 462885b47fbSopenharmony_ci if (isInterceptClick_ == false) { 463885b47fbSopenharmony_ci EventTransmission::OnPointerEvent(event); 464885b47fbSopenharmony_ci } 465885b47fbSopenharmony_ci} 466885b47fbSopenharmony_ci 467885b47fbSopenharmony_civoid AccessibilityScreenTouch::HandleIgnoreRepeatClickStateInnerUp(MMI::PointerEvent &event) 468885b47fbSopenharmony_ci{ 469885b47fbSopenharmony_ci HILOG_DEBUG(); 470885b47fbSopenharmony_ci 471885b47fbSopenharmony_ci if (isInterceptClick_ == false) { 472885b47fbSopenharmony_ci EventTransmission::OnPointerEvent(event); 473885b47fbSopenharmony_ci if (event.GetPointerIds().size() == POINTER_COUNT_1) { 474885b47fbSopenharmony_ci lastUpTime_ = event.GetActionTime(); 475885b47fbSopenharmony_ci } 476885b47fbSopenharmony_ci } 477885b47fbSopenharmony_ci} 478885b47fbSopenharmony_ci 479885b47fbSopenharmony_civoid AccessibilityScreenTouch::HandleIgnoreRepeatClickState(MMI::PointerEvent &event) 480885b47fbSopenharmony_ci{ 481885b47fbSopenharmony_ci HILOG_DEBUG(); 482885b47fbSopenharmony_ci switch (event.GetPointerAction()) { 483885b47fbSopenharmony_ci case MMI::PointerEvent::POINTER_ACTION_DOWN: 484885b47fbSopenharmony_ci HandleIgnoreRepeatClickStateInnerDown(event); 485885b47fbSopenharmony_ci break; 486885b47fbSopenharmony_ci case MMI::PointerEvent::POINTER_ACTION_MOVE: 487885b47fbSopenharmony_ci HandleIgnoreRepeatClickStateInnerMove(event); 488885b47fbSopenharmony_ci break; 489885b47fbSopenharmony_ci case MMI::PointerEvent::POINTER_ACTION_UP: 490885b47fbSopenharmony_ci HandleIgnoreRepeatClickStateInnerUp(event); 491885b47fbSopenharmony_ci break; 492885b47fbSopenharmony_ci default: 493885b47fbSopenharmony_ci EventTransmission::OnPointerEvent(event); 494885b47fbSopenharmony_ci break; 495885b47fbSopenharmony_ci } 496885b47fbSopenharmony_ci} 497885b47fbSopenharmony_ci 498885b47fbSopenharmony_civoid AccessibilityScreenTouch::HandleBothStateInnerDown(MMI::PointerEvent &event) 499885b47fbSopenharmony_ci{ 500885b47fbSopenharmony_ci HILOG_DEBUG(); 501885b47fbSopenharmony_ci 502885b47fbSopenharmony_ci int64_t downTime = event.GetActionTime(); 503885b47fbSopenharmony_ci if ((event.GetPointerIds().size() == POINTER_COUNT_1) && 504885b47fbSopenharmony_ci ((downTime - lastUpTime_) / US_TO_MS < GetRealIgnoreRepeatClickTime())) { 505885b47fbSopenharmony_ci isInterceptClick_ = true; 506885b47fbSopenharmony_ci return; 507885b47fbSopenharmony_ci } else if ((event.GetPointerIds().size() > POINTER_COUNT_1) && (isInterceptClick_ == true)) { 508885b47fbSopenharmony_ci return; 509885b47fbSopenharmony_ci } 510885b47fbSopenharmony_ci 511885b47fbSopenharmony_ci isInterceptClick_ = false; 512885b47fbSopenharmony_ci 513885b47fbSopenharmony_ci HandleResponseDelayStateInnerDown(event); 514885b47fbSopenharmony_ci} 515885b47fbSopenharmony_ci 516885b47fbSopenharmony_civoid AccessibilityScreenTouch::HandleBothStateInnerMove(MMI::PointerEvent &event) 517885b47fbSopenharmony_ci{ 518885b47fbSopenharmony_ci HILOG_DEBUG(); 519885b47fbSopenharmony_ci 520885b47fbSopenharmony_ci if (isInterceptClick_ == true) { 521885b47fbSopenharmony_ci return; 522885b47fbSopenharmony_ci } 523885b47fbSopenharmony_ci 524885b47fbSopenharmony_ci HandleResponseDelayStateInnerMove(event); 525885b47fbSopenharmony_ci} 526885b47fbSopenharmony_ci 527885b47fbSopenharmony_civoid AccessibilityScreenTouch::HandleBothStateInnerUp(MMI::PointerEvent &event) 528885b47fbSopenharmony_ci{ 529885b47fbSopenharmony_ci HILOG_DEBUG(); 530885b47fbSopenharmony_ci 531885b47fbSopenharmony_ci if (isInterceptClick_ == true) { 532885b47fbSopenharmony_ci return; 533885b47fbSopenharmony_ci } 534885b47fbSopenharmony_ci 535885b47fbSopenharmony_ci if (event.GetPointerIds().size() == POINTER_COUNT_1) { 536885b47fbSopenharmony_ci lastUpTime_ = event.GetActionTime(); 537885b47fbSopenharmony_ci } 538885b47fbSopenharmony_ci 539885b47fbSopenharmony_ci HandleResponseDelayStateInnerUp(event); 540885b47fbSopenharmony_ci} 541885b47fbSopenharmony_ci 542885b47fbSopenharmony_civoid AccessibilityScreenTouch::HandleBothState(MMI::PointerEvent &event) 543885b47fbSopenharmony_ci{ 544885b47fbSopenharmony_ci HILOG_DEBUG(); 545885b47fbSopenharmony_ci switch (event.GetPointerAction()) { 546885b47fbSopenharmony_ci case MMI::PointerEvent::POINTER_ACTION_DOWN: 547885b47fbSopenharmony_ci HandleBothStateInnerDown(event); 548885b47fbSopenharmony_ci break; 549885b47fbSopenharmony_ci case MMI::PointerEvent::POINTER_ACTION_MOVE: 550885b47fbSopenharmony_ci HandleBothStateInnerMove(event); 551885b47fbSopenharmony_ci break; 552885b47fbSopenharmony_ci case MMI::PointerEvent::POINTER_ACTION_UP: 553885b47fbSopenharmony_ci HandleBothStateInnerUp(event); 554885b47fbSopenharmony_ci break; 555885b47fbSopenharmony_ci default: 556885b47fbSopenharmony_ci EventTransmission::OnPointerEvent(event); 557885b47fbSopenharmony_ci break; 558885b47fbSopenharmony_ci } 559885b47fbSopenharmony_ci} 560885b47fbSopenharmony_ci 561885b47fbSopenharmony_civoid AccessibilityScreenTouch::Clear() 562885b47fbSopenharmony_ci{ 563885b47fbSopenharmony_ci isMoveBeyondThreshold_ = false; 564885b47fbSopenharmony_ci isInterceptClick_ = false; 565885b47fbSopenharmony_ci startPointer_ = nullptr; 566885b47fbSopenharmony_ci} 567885b47fbSopenharmony_ci 568885b47fbSopenharmony_cibool AccessibilityScreenTouch::OnPointerEvent(MMI::PointerEvent &event) 569885b47fbSopenharmony_ci{ 570885b47fbSopenharmony_ci HILOG_DEBUG(); 571885b47fbSopenharmony_ci MMI::PointerEvent::PointerItem pointerItem; 572885b47fbSopenharmony_ci if (!event.GetPointerItem(event.GetPointerId(), pointerItem)) { 573885b47fbSopenharmony_ci HILOG_WARN("get GetPointerItem %{public}d failed", event.GetPointerId()); 574885b47fbSopenharmony_ci return false; 575885b47fbSopenharmony_ci } 576885b47fbSopenharmony_ci if (pointerItem.GetToolType() == MMI::PointerEvent::TOOL_TYPE_KNUCKLE) { 577885b47fbSopenharmony_ci EventTransmission::OnPointerEvent(event); 578885b47fbSopenharmony_ci return false; 579885b47fbSopenharmony_ci } 580885b47fbSopenharmony_ci 581885b47fbSopenharmony_ci if (event.GetSourceType() != MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN) { 582885b47fbSopenharmony_ci EventTransmission::OnPointerEvent(event); 583885b47fbSopenharmony_ci return false; 584885b47fbSopenharmony_ci } 585885b47fbSopenharmony_ci 586885b47fbSopenharmony_ci if (event.GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_CANCEL) { 587885b47fbSopenharmony_ci Clear(); 588885b47fbSopenharmony_ci return true; 589885b47fbSopenharmony_ci } 590885b47fbSopenharmony_ci 591885b47fbSopenharmony_ci switch (currentState_) { 592885b47fbSopenharmony_ci case ScreenTouchState::CLICK_RESPONSE_DELAY_STATE: 593885b47fbSopenharmony_ci HandleResponseDelayState(event); 594885b47fbSopenharmony_ci break; 595885b47fbSopenharmony_ci case ScreenTouchState::IGNORE_REPEAT_CLICK_STATE: 596885b47fbSopenharmony_ci HandleIgnoreRepeatClickState(event); 597885b47fbSopenharmony_ci break; 598885b47fbSopenharmony_ci case ScreenTouchState::BOTH_RESPONSE_DELAY_IGNORE_REPEAT_CLICK: 599885b47fbSopenharmony_ci HandleBothState(event); 600885b47fbSopenharmony_ci break; 601885b47fbSopenharmony_ci case ScreenTouchState::DEFAULT_STATE: 602885b47fbSopenharmony_ci default: 603885b47fbSopenharmony_ci EventTransmission::OnPointerEvent(event); 604885b47fbSopenharmony_ci } 605885b47fbSopenharmony_ci 606885b47fbSopenharmony_ci return true; 607885b47fbSopenharmony_ci} 608885b47fbSopenharmony_ci} // namespace Accessibility 609885b47fbSopenharmony_ci} // namespace OHOS