1 /*
2 * Copyright (C) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "accessibility_zoom_gesture.h"
17 #include "accessible_ability_manager_service.h"
18 #include "hilog_wrapper.h"
19 #include "window_accessibility_controller.h"
20
21 namespace OHOS {
22 namespace Accessibility {
23 namespace {
24 constexpr size_t POINTER_COUNT_1 = 1;
25 constexpr float TAP_MIN_DISTANCE = 8.0f;
26 constexpr int32_t MULTI_TAP_TIMER = 300; // ms
27 constexpr int32_t LONG_PRESS_TIMER = 500; // ms
28 constexpr int64_t US_TO_MS = 1000;
29 constexpr float MIN_SCALE_SPAN = 26.0f;
30 constexpr float DOUBLE_TAP_SLOP = 100.0f;
31 constexpr float HALF = 0.5f;
32 constexpr uint32_t TRIPLE_TAP_COUNT = 3;
33 constexpr float DEFAULT_SCALE = 2.0f;
34 } // namespace
35
AccessibilityZoomGesture()36 AccessibilityZoomGesture::AccessibilityZoomGesture()
37 {
38 HILOG_DEBUG();
39
40 zoomGestureEventHandler_ = std::make_shared<ZoomGestureEventHandler>(
41 Singleton<AccessibleAbilityManagerService>::GetInstance().GetMainRunner(), *this);
42
43 tapDistance_ = TAP_MIN_DISTANCE;
44
45 AccessibilityDisplayManager &displayMgr = Singleton<AccessibilityDisplayManager>::GetInstance();
46 auto display = displayMgr.GetDefaultDisplay();
47 if (!display) {
48 HILOG_ERROR("get display is nullptr");
49 return;
50 }
51
52 float densityPixels = display->GetVirtualPixelRatio();
53 multiTapDistance_ = densityPixels * DOUBLE_TAP_SLOP + 0.5f;
54 }
55
OnPointerEvent(MMI::PointerEvent & event)56 bool AccessibilityZoomGesture::OnPointerEvent(MMI::PointerEvent &event)
57 {
58 HILOG_DEBUG("state_ is %{public}d.", state_);
59
60 int32_t sourceType = event.GetSourceType();
61 if (sourceType != MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
62 EventTransmission::OnPointerEvent(event);
63 return false;
64 }
65
66 switch (state_) {
67 case READY_STATE:
68 CacheEvents(event);
69 RecognizeInReadyState(event);
70 break;
71 case ZOOMIN_STATE:
72 CacheEvents(event);
73 RecognizeInZoomState(event);
74 break;
75 case SLIDING_STATE:
76 RecognizeInSlidingState(event);
77 break;
78 default:
79 break;
80 }
81 return true;
82 }
83
TransferState(ACCESSIBILITY_ZOOM_STATE state)84 void AccessibilityZoomGesture::TransferState(ACCESSIBILITY_ZOOM_STATE state)
85 {
86 HILOG_DEBUG("state:%{public}d.", state);
87
88 state_ = state;
89 }
90
CacheEvents(MMI::PointerEvent & event)91 void AccessibilityZoomGesture::CacheEvents(MMI::PointerEvent &event)
92 {
93 HILOG_DEBUG();
94
95 int32_t action = event.GetPointerAction();
96 size_t pointerCount = event.GetPointerIds().size();
97 std::shared_ptr<MMI::PointerEvent> pointerEvent = std::make_shared<MMI::PointerEvent>(event);
98
99 switch (action) {
100 case MMI::PointerEvent::POINTER_ACTION_DOWN:
101 if (pointerCount == POINTER_COUNT_1) {
102 HILOG_DEBUG("Cache pointer down");
103 preLastDownEvent_ = lastDownEvent_;
104 lastDownEvent_ = pointerEvent;
105 }
106 break;
107 case MMI::PointerEvent::POINTER_ACTION_UP:
108 if (pointerCount == POINTER_COUNT_1) {
109 HILOG_DEBUG("Cache pointer up");
110 preLastUpEvent_ = lastUpEvent_;
111 lastUpEvent_ = pointerEvent;
112 }
113 break;
114 default:
115 HILOG_DEBUG("Action is %{public}d", action);
116 break;
117 }
118 cacheEvents_.emplace_back(pointerEvent);
119 }
120
SendCacheEventsToNext()121 void AccessibilityZoomGesture::SendCacheEventsToNext()
122 {
123 HILOG_DEBUG();
124
125 bool isStartNewAction = false;
126 int32_t action = MMI::PointerEvent::POINTER_ACTION_UNKNOWN;
127 std::vector<std::shared_ptr<MMI::PointerEvent>> cacheEventsTmp;
128 std::copy(cacheEvents_.begin(), cacheEvents_.end(), std::back_inserter(cacheEventsTmp));
129
130 ClearCacheEventsAndMsg();
131
132 size_t cacheEventsNum = 0;
133 size_t cacheEventsTotalNum = cacheEventsTmp.size();
134 for (auto &pointerEvent : cacheEventsTmp) {
135 cacheEventsNum++;
136 action = pointerEvent->GetPointerAction();
137 if ((cacheEventsNum > 1) &&
138 (cacheEventsNum == cacheEventsTotalNum) &&
139 (action == MMI::PointerEvent::POINTER_ACTION_DOWN)) {
140 HILOG_DEBUG("The down event needs to be parsed again");
141 isStartNewAction = true;
142 }
143 if (isStartNewAction) {
144 OnPointerEvent(*pointerEvent);
145 } else {
146 EventTransmission::OnPointerEvent(*pointerEvent);
147 }
148 }
149 }
150
ClearCacheEventsAndMsg()151 void AccessibilityZoomGesture::ClearCacheEventsAndMsg()
152 {
153 HILOG_DEBUG();
154
155 cacheEvents_.clear();
156 preLastDownEvent_ = nullptr;
157 lastDownEvent_ = nullptr;
158 preLastUpEvent_ = nullptr;
159 lastUpEvent_ = nullptr;
160 zoomGestureEventHandler_->RemoveEvent(MULTI_TAP_MSG);
161 }
162
RecognizeInReadyState(MMI::PointerEvent & event)163 void AccessibilityZoomGesture::RecognizeInReadyState(MMI::PointerEvent &event)
164 {
165 HILOG_DEBUG();
166
167 int32_t action = event.GetPointerAction();
168 size_t pointerCount = event.GetPointerIds().size();
169 bool isTripleTaps = false;
170
171 HILOG_DEBUG("action:%{public}d, pointerCount:%{public}zu", action, pointerCount);
172 switch (action) {
173 case MMI::PointerEvent::POINTER_ACTION_DOWN:
174 zoomGestureEventHandler_->RemoveEvent(MULTI_TAP_MSG);
175 if ((pointerCount == POINTER_COUNT_1) && IsDownValid()) {
176 zoomGestureEventHandler_->SendEvent(MULTI_TAP_MSG, 0, MULTI_TAP_TIMER);
177 } else {
178 SendCacheEventsToNext();
179 }
180 break;
181 case MMI::PointerEvent::POINTER_ACTION_UP:
182 if ((pointerCount == POINTER_COUNT_1) && IsUpValid()) {
183 isTripleTaps = IsTripleTaps();
184 } else {
185 SendCacheEventsToNext();
186 HILOG_DEBUG("action:%{public}d, pointerCount:%{public}zu", action, pointerCount);
187 }
188 break;
189 case MMI::PointerEvent::POINTER_ACTION_CANCEL:
190 SendCacheEventsToNext();
191 break;
192 default:
193 break;
194 }
195
196 if (isTripleTaps) {
197 OnTripleTaps(event);
198 }
199 }
200
RecognizeInZoomState(MMI::PointerEvent & event)201 void AccessibilityZoomGesture::RecognizeInZoomState(MMI::PointerEvent &event)
202 {
203 HILOG_DEBUG();
204
205 int32_t action = event.GetPointerAction();
206 size_t pointerCount = event.GetPointerIds().size();
207 bool isTripleTaps = false;
208
209 HILOG_DEBUG("action:%{public}d, pointerCount:%{public}zu", action, pointerCount);
210 switch (action) {
211 case MMI::PointerEvent::POINTER_ACTION_DOWN:
212 zoomGestureEventHandler_->RemoveEvent(MULTI_TAP_MSG);
213 if (pointerCount == POINTER_COUNT_1) {
214 if (IsDownValid()) {
215 zoomGestureEventHandler_->SendEvent(MULTI_TAP_MSG, 0, MULTI_TAP_TIMER);
216 } else {
217 SendCacheEventsToNext();
218 }
219 } else if (pointerCount > POINTER_COUNT_1) {
220 TransferState(SLIDING_STATE);
221 ClearCacheEventsAndMsg();
222 ZOOM_FOCUS_COORDINATE focusXY = {0.0f, 0.0f};
223 CalcFocusCoordinate(event, focusXY);
224 // Used for scroll algorithm.
225 lastScrollFocusX_ = focusXY.centerX;
226 lastScrollFocusY_ = focusXY.centerY;
227
228 // Used for scale algorithm.
229 float span = CalcScaleSpan(event, focusXY);
230 if (span >= MIN_SCALE_SPAN) {
231 startScaling_ = true;
232 preSpan_ = lastSpan_ = span;
233 }
234 }
235 break;
236 case MMI::PointerEvent::POINTER_ACTION_UP:
237 if ((pointerCount == POINTER_COUNT_1) && IsUpValid()) {
238 isTripleTaps = IsTripleTaps();
239 } else {
240 SendCacheEventsToNext();
241 }
242 break;
243 case MMI::PointerEvent::POINTER_ACTION_CANCEL:
244 SendCacheEventsToNext();
245 HILOG_DEBUG("action:%{public}d", action);
246 break;
247 default:
248 break;
249 }
250
251 if (isTripleTaps) {
252 OnTripleTaps(event);
253 }
254 }
255
RecognizeInSlidingState(MMI::PointerEvent & event)256 void AccessibilityZoomGesture::RecognizeInSlidingState(MMI::PointerEvent &event)
257 {
258 HILOG_DEBUG();
259
260 int32_t action = event.GetPointerAction();
261 size_t pointerCount = event.GetPointerIds().size();
262
263 // Recognize scroll and zoom gestures.
264 RecognizeScroll(event);
265 RecognizeScale(event);
266
267 HILOG_DEBUG("action:%{public}d, pointerCount:%{public}zu", action, pointerCount);
268 switch (action) {
269 case MMI::PointerEvent::POINTER_ACTION_UP:
270 if (pointerCount == POINTER_COUNT_1) {
271 TransferState(ZOOMIN_STATE);
272 }
273 break;
274 case MMI::PointerEvent::POINTER_ACTION_CANCEL:
275 TransferState(ZOOMIN_STATE);
276 break;
277 default:
278 break;
279 }
280 }
281
RecognizeScroll(MMI::PointerEvent & event)282 void AccessibilityZoomGesture::RecognizeScroll(MMI::PointerEvent &event)
283 {
284 HILOG_DEBUG();
285
286 int32_t action = event.GetPointerAction();
287 ZOOM_FOCUS_COORDINATE coordinate = {0.0f, 0.0f};
288 CalcFocusCoordinate(event, coordinate);
289
290 switch (action) {
291 case MMI::PointerEvent::POINTER_ACTION_DOWN:
292 case MMI::PointerEvent::POINTER_ACTION_UP:
293 lastScrollFocusX_ = coordinate.centerX;
294 lastScrollFocusY_ = coordinate.centerY;
295 break;
296 case MMI::PointerEvent::POINTER_ACTION_MOVE: {
297 float offsetX = coordinate.centerX - lastScrollFocusX_;
298 float offsetY = coordinate.centerY - lastScrollFocusY_;
299 if ((abs(offsetX) > 1) || (abs(offsetY) > 1)) {
300 lastScrollFocusX_ = coordinate.centerX;
301 lastScrollFocusY_ = coordinate.centerY;
302 OnScroll(offsetX, offsetY);
303 }
304 break;
305 }
306 default:
307 break;
308 }
309 }
310
RecognizeScale(MMI::PointerEvent & event)311 void AccessibilityZoomGesture::RecognizeScale(MMI::PointerEvent &event)
312 {
313 HILOG_DEBUG();
314
315 int32_t action = event.GetPointerAction();
316 size_t pointerCount = event.GetPointerIds().size();
317 if (((action == MMI::PointerEvent::POINTER_ACTION_UP) && (pointerCount == POINTER_COUNT_1)) ||
318 (action == MMI::PointerEvent::POINTER_ACTION_CANCEL)) {
319 HILOG_DEBUG("Scaling is end");
320 startScaling_ = false;
321 preSpan_ = lastSpan_ = 0;
322 return;
323 }
324
325 ZOOM_FOCUS_COORDINATE focusXY = {0.0f, 0.0f};
326 CalcFocusCoordinate(event, focusXY);
327 float span = CalcScaleSpan(event, focusXY);
328 if (!startScaling_) {
329 // When the span is greater than or equal to MIN_SCALE_SPAN, start scaling.
330 if (span >= MIN_SCALE_SPAN) {
331 startScaling_ = true;
332 preSpan_ = lastSpan_ = span;
333 }
334 } else {
335 // When the span is smaller than the MIN_SCALE_SPAN,
336 // the scale recognition will be restarted.
337 if (span < MIN_SCALE_SPAN) {
338 startScaling_ = false;
339 preSpan_ = lastSpan_ = span;
340 }
341 if ((action == MMI::PointerEvent::POINTER_ACTION_UP) ||
342 (action == MMI::PointerEvent::POINTER_ACTION_DOWN)) {
343 preSpan_ = lastSpan_ = span;
344 }
345 }
346
347 if (!startScaling_) {
348 HILOG_DEBUG("Current is not scaling");
349 return;
350 }
351
352 if (action != MMI::PointerEvent::POINTER_ACTION_MOVE) {
353 HILOG_DEBUG("Action(%{public}d) is not move", action);
354 return;
355 }
356
357 lastSpan_ = span;
358 float ratio = lastSpan_ / preSpan_;
359 if (ratio != 1) {
360 OnScale(ratio, focusXY.centerX, focusXY.centerY);
361 preSpan_ = lastSpan_;
362 }
363 }
364
CalcFocusCoordinate(MMI::PointerEvent & event,ZOOM_FOCUS_COORDINATE & coordinate)365 void AccessibilityZoomGesture::CalcFocusCoordinate(MMI::PointerEvent &event, ZOOM_FOCUS_COORDINATE &coordinate)
366 {
367 HILOG_DEBUG();
368
369 float sumX = 0.0f;
370 float sumY = 0.0f;
371 int32_t upPointerId = -1;
372 int32_t action = event.GetPointerAction();
373 std::vector<int32_t> pointerIdList = event.GetPointerIds();
374 size_t count = pointerIdList.size();
375 if (!count) {
376 HILOG_DEBUG("The size of PointerIds is 0");
377 return;
378 }
379
380 if (action == MMI::PointerEvent::POINTER_ACTION_UP) {
381 upPointerId = event.GetPointerId();
382 HILOG_DEBUG("The pointer id of up is %{public}d", upPointerId);
383 count--;
384 }
385
386 if (!count) {
387 HILOG_DEBUG("The size of PointerIds(down) is invalid");
388 return;
389 }
390
391 for (int32_t pointerId : pointerIdList) {
392 if (pointerId == upPointerId) {
393 continue;
394 }
395 MMI::PointerEvent::PointerItem item;
396 event.GetPointerItem(pointerId, item);
397 sumX += static_cast<float>(item.GetDisplayX());
398 sumY += static_cast<float>(item.GetDisplayY());
399 }
400
401 coordinate.centerX = sumX / count;
402 coordinate.centerY = sumY / count;
403 HILOG_DEBUG("centerX:%{public}f, centerY:%{public}f", coordinate.centerX, coordinate.centerY);
404 }
405
CalcScaleSpan(MMI::PointerEvent & event,ZOOM_FOCUS_COORDINATE coordinate)406 float AccessibilityZoomGesture::CalcScaleSpan(MMI::PointerEvent &event, ZOOM_FOCUS_COORDINATE coordinate)
407 {
408 HILOG_DEBUG();
409
410 float span = 0.0f;
411 float sumSpanX = 0.0f;
412 float sumSpanY = 0.0f;
413 int32_t upPointerId = -1;
414 int32_t action = event.GetPointerAction();
415 std::vector<int32_t> pointerIdList = event.GetPointerIds();
416 size_t count = pointerIdList.size();
417 if (!count) {
418 HILOG_DEBUG("The size of PointerIds is 0");
419 return span;
420 }
421
422 if (action == MMI::PointerEvent::POINTER_ACTION_UP) {
423 upPointerId = event.GetPointerId();
424 HILOG_DEBUG("The pointer id of up is %{public}d", upPointerId);
425 count--;
426 }
427
428 if (!count) {
429 HILOG_DEBUG("The size of PointerIds(down) is invalid");
430 return span;
431 }
432
433 for (int32_t pointerId : pointerIdList) {
434 if (pointerId == upPointerId) {
435 continue;
436 }
437 MMI::PointerEvent::PointerItem item;
438 event.GetPointerItem(pointerId, item);
439 sumSpanX += static_cast<float>(abs(item.GetDisplayX() - coordinate.centerX));
440 sumSpanY += static_cast<float>(abs(item.GetDisplayY() - coordinate.centerY));
441 }
442
443 float spanX = sumSpanX / count;
444 float spanY = sumSpanY / count;
445 span = hypot(spanX, spanY) / HALF;
446 HILOG_DEBUG("The span is %{public}f", span);
447 return span;
448 }
449
IsDownValid()450 bool AccessibilityZoomGesture::IsDownValid()
451 {
452 HILOG_DEBUG();
453
454 if (!preLastDownEvent_) {
455 HILOG_DEBUG("This is the first down event");
456 return true;
457 }
458
459 if (CalcSeparationDistance(preLastDownEvent_, lastDownEvent_) >= multiTapDistance_) {
460 HILOG_DEBUG("The down event is vailid");
461 return false;
462 }
463 return true;
464 }
465
IsUpValid()466 bool AccessibilityZoomGesture::IsUpValid()
467 {
468 HILOG_DEBUG();
469
470 if (!lastDownEvent_) {
471 HILOG_DEBUG("The up event is invailid");
472 return false;
473 }
474
475 if (CalcIntervalTime(lastDownEvent_, lastUpEvent_) >= LONG_PRESS_TIMER) {
476 HILOG_DEBUG("The time has exceeded the long press time");
477 return false;
478 }
479
480 if (CalcSeparationDistance(lastDownEvent_, lastUpEvent_) >= tapDistance_) {
481 HILOG_DEBUG("The distance has exceeded the threshold");
482 return false;
483 }
484 return true;
485 }
486
IsTripleTaps()487 bool AccessibilityZoomGesture::IsTripleTaps()
488 {
489 HILOG_DEBUG();
490
491 uint32_t upEventCount = 0;
492 int32_t action = MMI::PointerEvent::POINTER_ACTION_UNKNOWN;
493 for (auto &pointerEvent : cacheEvents_) {
494 action = pointerEvent->GetPointerAction();
495 if (action == MMI::PointerEvent::POINTER_ACTION_UP) {
496 upEventCount++;
497 }
498 }
499
500 if (upEventCount >= TRIPLE_TAP_COUNT) {
501 HILOG_DEBUG("Triple tap detected");
502 return true;
503 }
504
505 return false;
506 }
507
CalcIntervalTime(std::shared_ptr<MMI::PointerEvent> firstEvent,std::shared_ptr<MMI::PointerEvent> secondEvent)508 int64_t AccessibilityZoomGesture::CalcIntervalTime(std::shared_ptr<MMI::PointerEvent> firstEvent,
509 std::shared_ptr<MMI::PointerEvent> secondEvent)
510 {
511 HILOG_DEBUG();
512
513 if (!firstEvent || !secondEvent) {
514 HILOG_DEBUG("The event is null");
515 return 0;
516 }
517
518 int64_t firstTime = firstEvent->GetActionTime();
519 int64_t secondTime = secondEvent->GetActionTime();
520 int64_t intervalTime = (secondTime - firstTime) / US_TO_MS;
521
522 return intervalTime;
523 }
524
CalcSeparationDistance(std::shared_ptr<MMI::PointerEvent> firstEvent,std::shared_ptr<MMI::PointerEvent> secondEvent)525 float AccessibilityZoomGesture::CalcSeparationDistance(std::shared_ptr<MMI::PointerEvent> firstEvent,
526 std::shared_ptr<MMI::PointerEvent> secondEvent)
527 {
528 HILOG_DEBUG();
529
530 if (!firstEvent || !secondEvent) {
531 HILOG_DEBUG("The event is null");
532 return 0;
533 }
534
535 MMI::PointerEvent::PointerItem firstItem;
536 MMI::PointerEvent::PointerItem secondItem;
537 firstEvent->GetPointerItem(firstEvent->GetPointerId(), firstItem);
538 secondEvent->GetPointerItem(secondEvent->GetPointerId(), secondItem);
539 int32_t durationX = secondItem.GetDisplayX() - firstItem.GetDisplayX();
540 int32_t durationY = secondItem.GetDisplayY() - firstItem.GetDisplayY();
541 float distance = static_cast<float>(hypot(durationX, durationY));
542
543 return distance;
544 }
545
OnTripleTaps(MMI::PointerEvent & event)546 void AccessibilityZoomGesture::OnTripleTaps(MMI::PointerEvent &event)
547 {
548 HILOG_DEBUG("state_ is %{public}d.", state_);
549
550 switch (state_) {
551 case READY_STATE: {
552 TransferState(ZOOMIN_STATE);
553 int32_t pointerId = event.GetPointerId();
554 MMI::PointerEvent::PointerItem item;
555 event.GetPointerItem(pointerId, item);
556 int32_t anchorX = item.GetDisplayX();
557 int32_t anchorY = item.GetDisplayY();
558 OnZoom(anchorX, anchorY);
559 break;
560 }
561 case ZOOMIN_STATE:
562 TransferState(READY_STATE);
563 OffZoom();
564 break;
565 default:
566 break;
567 }
568
569 ClearCacheEventsAndMsg();
570 }
571
ZoomGestureEventHandler(const std::shared_ptr<AppExecFwk::EventRunner> & runner,AccessibilityZoomGesture & zoomGesture)572 AccessibilityZoomGesture::ZoomGestureEventHandler::ZoomGestureEventHandler(
573 const std::shared_ptr<AppExecFwk::EventRunner> &runner,
574 AccessibilityZoomGesture &zoomGesture): AppExecFwk::EventHandler(runner), zoomGesture_(zoomGesture)
575 {
576 HILOG_DEBUG();
577 }
578
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)579 void AccessibilityZoomGesture::ZoomGestureEventHandler::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
580 {
581 HILOG_DEBUG();
582
583 uint32_t eventId = event->GetInnerEventId();
584
585 switch (eventId) {
586 case MULTI_TAP_MSG:
587 zoomGesture_.SendCacheEventsToNext();
588 break;
589 default:
590 break;
591 }
592 }
593
OnZoom(int32_t anchorX,int32_t anchorY)594 void AccessibilityZoomGesture::OnZoom(int32_t anchorX, int32_t anchorY)
595 {
596 HILOG_DEBUG("anchorX:%{public}d, anchorY:%{public}d.", anchorX, anchorY);
597
598 OHOS::Rosen::WindowAccessibilityController::GetInstance().SetAnchorAndScale(anchorX, anchorY, DEFAULT_SCALE);
599 }
600
OffZoom()601 void AccessibilityZoomGesture::OffZoom()
602 {
603 HILOG_DEBUG();
604
605 OHOS::Rosen::WindowAccessibilityController::GetInstance().OffWindowZoom();
606 }
607
OnScroll(float offsetX,float offsetY)608 void AccessibilityZoomGesture::OnScroll(float offsetX, float offsetY)
609 {
610 HILOG_DEBUG("offsetX:%{public}f, offsetY:%{public}f.", offsetX, offsetY);
611
612 OHOS::Rosen::WindowAccessibilityController::GetInstance().SetAnchorOffset(
613 static_cast<int32_t>(offsetX), static_cast<int32_t>(offsetY));
614 }
615
OnScale(float scaleRatio,float focusX,float focusY)616 void AccessibilityZoomGesture::OnScale(float scaleRatio, float focusX, float focusY)
617 {
618 HILOG_DEBUG("scaleRatio:%{public}f, focusX:%{public}f, focusY:%{public}f.", scaleRatio, focusX, focusY);
619
620 OHOS::Rosen::WindowAccessibilityController::GetInstance().SetAnchorAndScale(
621 static_cast<int32_t>(focusX), static_cast<int32_t>(focusY), scaleRatio);
622 }
623 } // namespace Accessibility
624 } // namespace OHOS
625