OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/renderer_host/input/synthetic_gesture_controller.h" | 5 #include "content/browser/renderer_host/input/synthetic_gesture_controller.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <memory> | 10 #include <memory> |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
48 namespace { | 48 namespace { |
49 | 49 |
50 const int kFlushInputRateInMs = 16; | 50 const int kFlushInputRateInMs = 16; |
51 const int kPointerAssumedStoppedTimeMs = 43; | 51 const int kPointerAssumedStoppedTimeMs = 43; |
52 const float kTouchSlopInDips = 7.0f; | 52 const float kTouchSlopInDips = 7.0f; |
53 const float kMinScalingSpanInDips = 27.5f; | 53 const float kMinScalingSpanInDips = 27.5f; |
54 const int kTouchPointersLength = 16; | 54 const int kTouchPointersLength = 16; |
55 | 55 |
56 enum TouchGestureType { TOUCH_SCROLL, TOUCH_DRAG }; | 56 enum TouchGestureType { TOUCH_SCROLL, TOUCH_DRAG }; |
57 | 57 |
58 WebTouchPoint::State ToWebTouchPointState( | |
59 SyntheticPointerActionParams::PointerActionType action_type) { | |
60 switch (action_type) { | |
61 case SyntheticPointerActionParams::PointerActionType::PRESS: | |
62 return WebTouchPoint::StatePressed; | |
63 case SyntheticPointerActionParams::PointerActionType::MOVE: | |
64 return WebTouchPoint::StateMoved; | |
65 case SyntheticPointerActionParams::PointerActionType::RELEASE: | |
66 return WebTouchPoint::StateReleased; | |
67 case SyntheticPointerActionParams::PointerActionType::IDLE: | |
68 return WebTouchPoint::StateStationary; | |
69 case SyntheticPointerActionParams::PointerActionType::NOT_INITIALIZED: | |
70 NOTREACHED() | |
71 << "Invalid SyntheticPointerActionParams::PointerActionType."; | |
72 return WebTouchPoint::StateUndefined; | |
73 } | |
74 NOTREACHED() << "Invalid SyntheticPointerActionParams::PointerActionType."; | |
75 return WebTouchPoint::StateUndefined; | |
samuong
2016/12/21 00:02:26
should this last check be handled by a default: ca
lanwei
2016/12/21 20:01:13
We already covered all the cased in the switch sta
samuong
2016/12/21 20:39:22
Hmm ok. It works fine for me with clang on linux,
| |
76 } | |
77 | |
78 WebInputEvent::Type ToWebMouseEventType( | |
79 SyntheticPointerActionParams::PointerActionType action_type) { | |
80 switch (action_type) { | |
81 case SyntheticPointerActionParams::PointerActionType::PRESS: | |
82 return WebInputEvent::MouseDown; | |
83 case SyntheticPointerActionParams::PointerActionType::MOVE: | |
84 return WebInputEvent::MouseMove; | |
85 case SyntheticPointerActionParams::PointerActionType::RELEASE: | |
86 return WebInputEvent::MouseUp; | |
87 case SyntheticPointerActionParams::PointerActionType::IDLE: | |
88 case SyntheticPointerActionParams::PointerActionType::NOT_INITIALIZED: | |
89 NOTREACHED() | |
90 << "Invalid SyntheticPointerActionParams::PointerActionType."; | |
91 return WebInputEvent::Undefined; | |
92 } | |
93 NOTREACHED() << "Invalid SyntheticPointerActionParams::PointerActionType."; | |
94 return WebInputEvent::Undefined; | |
95 } | |
96 | |
58 class MockSyntheticGesture : public SyntheticGesture { | 97 class MockSyntheticGesture : public SyntheticGesture { |
59 public: | 98 public: |
60 MockSyntheticGesture(bool* finished, int num_steps) | 99 MockSyntheticGesture(bool* finished, int num_steps) |
61 : finished_(finished), | 100 : finished_(finished), |
62 num_steps_(num_steps), | 101 num_steps_(num_steps), |
63 step_count_(0) { | 102 step_count_(0) { |
64 *finished_ = false; | 103 *finished_ = false; |
65 } | 104 } |
66 ~MockSyntheticGesture() override {} | 105 ~MockSyntheticGesture() override {} |
67 | 106 |
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
467 break; | 506 break; |
468 case FINISHED: | 507 case FINISHED: |
469 EXPECT_FALSE(true); | 508 EXPECT_FALSE(true); |
470 break; | 509 break; |
471 } | 510 } |
472 } | 511 } |
473 }; | 512 }; |
474 | 513 |
475 class MockSyntheticPointerActionTarget : public MockSyntheticGestureTarget { | 514 class MockSyntheticPointerActionTarget : public MockSyntheticGestureTarget { |
476 public: | 515 public: |
477 MockSyntheticPointerActionTarget() {} | 516 MockSyntheticPointerActionTarget() : actions_dispatched_times_(0) {} |
478 ~MockSyntheticPointerActionTarget() override {} | 517 ~MockSyntheticPointerActionTarget() override {} |
479 | 518 |
480 gfx::PointF positions(int index) const { return positions_[index]; } | |
481 int indexes(int index) const { return indexes_[index]; } | |
482 WebTouchPoint::State states(int index) { return states_[index]; } | |
483 unsigned touch_length() const { return touch_length_; } | |
484 WebInputEvent::Type type() const { return type_; } | 519 WebInputEvent::Type type() const { return type_; } |
520 int actions_dispatched_times() const { return actions_dispatched_times_; } | |
521 void reset_actions_dispatched_times() { actions_dispatched_times_ = 0; } | |
485 | 522 |
486 protected: | 523 protected: |
487 gfx::PointF positions_[kTouchPointersLength]; | |
488 unsigned touch_length_; | |
489 int indexes_[kTouchPointersLength]; | |
490 WebTouchPoint::State states_[kTouchPointersLength]; | |
491 WebInputEvent::Type type_; | 524 WebInputEvent::Type type_; |
525 int actions_dispatched_times_; | |
samuong
2016/12/21 00:02:26
This name is a bit confusing. What do you think of
lanwei
2016/12/21 20:01:14
Done.
| |
492 }; | 526 }; |
493 | 527 |
494 class MockSyntheticPointerTouchActionTarget | 528 class MockSyntheticPointerTouchActionTarget |
495 : public MockSyntheticPointerActionTarget { | 529 : public MockSyntheticPointerActionTarget { |
496 public: | 530 public: |
497 MockSyntheticPointerTouchActionTarget() {} | 531 MockSyntheticPointerTouchActionTarget() {} |
498 ~MockSyntheticPointerTouchActionTarget() override {} | 532 ~MockSyntheticPointerTouchActionTarget() override {} |
499 | 533 |
500 void DispatchInputEventToPlatform(const WebInputEvent& event) override { | 534 void DispatchInputEventToPlatform(const WebInputEvent& event) override { |
501 ASSERT_TRUE(WebInputEvent::isTouchEventType(event.type)); | 535 DCHECK(WebInputEvent::isTouchEventType(event.type)); |
502 const WebTouchEvent& touch_event = static_cast<const WebTouchEvent&>(event); | 536 const WebTouchEvent& touch_event = static_cast<const WebTouchEvent&>(event); |
503 type_ = touch_event.type; | 537 type_ = touch_event.type; |
504 for (size_t i = 0; i < touch_event.touchesLength; ++i) { | 538 for (size_t i = 0; i < WebTouchEvent::kTouchesLengthCap; ++i) { |
505 indexes_[i] = touch_event.touches[i].id; | 539 indexes_[i] = touch_event.touches[i].id; |
506 positions_[i] = gfx::PointF(touch_event.touches[i].position); | 540 positions_[i] = gfx::PointF(touch_event.touches[i].position); |
507 states_[i] = touch_event.touches[i].state; | 541 states_[i] = touch_event.touches[i].state; |
508 } | 542 } |
509 touch_length_ = touch_event.touchesLength; | 543 touch_length_ = touch_event.touchesLength; |
544 actions_dispatched_times_++; | |
510 } | 545 } |
546 | |
547 testing::AssertionResult SyntheticTouchActionDispatchedCorrectly( | |
548 const SyntheticPointerActionParams& param, | |
549 int index) { | |
550 if (param.pointer_action_type() == | |
551 SyntheticPointerActionParams::PointerActionType::PRESS || | |
552 param.pointer_action_type() == | |
553 SyntheticPointerActionParams::PointerActionType::MOVE) { | |
554 if (indexes_[index] != param.index()) { | |
555 return testing::AssertionFailure() | |
556 << "Pointer index at index " << index << " was " | |
557 << indexes_[index] << ", expected " << param.index() << "."; | |
558 } | |
559 | |
560 if (positions_[index] != param.position()) { | |
561 return testing::AssertionFailure() | |
562 << "Pointer position at index " << index << " was " | |
563 << positions_[index].ToString() << ", expected " | |
564 << param.position().ToString() << "."; | |
565 } | |
566 } | |
567 | |
568 if (states_[index] != ToWebTouchPointState(param.pointer_action_type())) { | |
569 return testing::AssertionFailure() | |
570 << "Pointer states at index " << index << " was " << states_[index] | |
571 << ", expected " | |
572 << ToWebTouchPointState(param.pointer_action_type()) << "."; | |
573 } | |
574 return testing::AssertionSuccess(); | |
575 } | |
576 | |
577 testing::AssertionResult SyntheticTouchActionListDispatchedCorrectly( | |
578 const std::vector<SyntheticPointerActionParams>& params_list) { | |
579 if (touch_length_ != params_list.size()) { | |
580 return testing::AssertionFailure() << "Touch point length was " | |
581 << touch_length_ << ", expected " | |
582 << params_list.size() << "."; | |
583 } | |
584 | |
585 testing::AssertionResult result = testing::AssertionSuccess(); | |
586 for (size_t i = 0; i < params_list.size(); ++i) { | |
587 result = SyntheticTouchActionDispatchedCorrectly(params_list[i], | |
588 params_list[i].index()); | |
589 if (result == testing::AssertionFailure()) | |
590 return result; | |
591 } | |
592 return testing::AssertionSuccess(); | |
593 } | |
594 | |
595 private: | |
596 gfx::PointF positions_[kTouchPointersLength]; | |
597 unsigned touch_length_; | |
598 int indexes_[kTouchPointersLength]; | |
599 WebTouchPoint::State states_[kTouchPointersLength]; | |
600 }; | |
601 | |
602 class MockSyntheticPointerMouseActionTarget | |
603 : public MockSyntheticPointerActionTarget { | |
604 public: | |
605 MockSyntheticPointerMouseActionTarget() {} | |
606 ~MockSyntheticPointerMouseActionTarget() override {} | |
607 | |
608 void DispatchInputEventToPlatform(const WebInputEvent& event) override { | |
609 ASSERT_TRUE(WebInputEvent::isMouseEventType(event.type)); | |
610 const WebMouseEvent& mouse_event = static_cast<const WebMouseEvent&>(event); | |
611 type_ = mouse_event.type; | |
612 position_ = gfx::PointF(mouse_event.x, mouse_event.y); | |
613 clickCount_ = mouse_event.clickCount; | |
614 button_ = mouse_event.button; | |
615 actions_dispatched_times_++; | |
616 } | |
617 | |
618 testing::AssertionResult SyntheticMouseActionDispatchedCorrectly( | |
619 const SyntheticPointerActionParams& param, | |
620 int click_count) { | |
621 if (type_ != ToWebMouseEventType(param.pointer_action_type())) { | |
622 return testing::AssertionFailure() | |
623 << "Pointer type was " << WebInputEvent::GetName(type_) | |
624 << ", expected " << WebInputEvent::GetName(ToWebMouseEventType( | |
625 param.pointer_action_type())) << "."; | |
626 } | |
627 | |
628 if (clickCount_ != click_count) { | |
629 return testing::AssertionFailure() << "Pointer click count was " | |
630 << clickCount_ << ", expected " | |
631 << click_count << "."; | |
632 } | |
633 | |
634 if (clickCount_ == 1 && button_ != WebMouseEvent::Button::Left) { | |
635 return testing::AssertionFailure() | |
636 << "Pointer button was " << (int)button_ << ", expected " | |
637 << (int)WebMouseEvent::Button::Left << "."; | |
638 } | |
639 | |
640 if (clickCount_ == 0 && button_ != WebMouseEvent::Button::NoButton) { | |
641 return testing::AssertionFailure() | |
642 << "Pointer button was " << (int)button_ << ", expected " | |
643 << (int)WebMouseEvent::Button::NoButton << "."; | |
644 } | |
645 | |
646 if ((param.pointer_action_type() == | |
647 SyntheticPointerActionParams::PointerActionType::PRESS || | |
648 param.pointer_action_type() == | |
649 SyntheticPointerActionParams::PointerActionType::MOVE) && | |
650 position_ != param.position()) { | |
651 return testing::AssertionFailure() | |
652 << "Pointer position was " << position_.ToString() | |
653 << ", expected " << param.position().ToString() << "."; | |
654 } | |
655 return testing::AssertionSuccess(); | |
656 } | |
657 | |
658 private: | |
659 gfx::PointF position_; | |
660 int clickCount_; | |
661 WebMouseEvent::Button button_; | |
511 }; | 662 }; |
512 | 663 |
513 class SyntheticGestureControllerTestBase { | 664 class SyntheticGestureControllerTestBase { |
514 public: | 665 public: |
515 SyntheticGestureControllerTestBase() {} | 666 SyntheticGestureControllerTestBase() {} |
516 ~SyntheticGestureControllerTestBase() {} | 667 ~SyntheticGestureControllerTestBase() {} |
517 | 668 |
518 protected: | 669 protected: |
519 template<typename MockGestureTarget> | 670 template<typename MockGestureTarget> |
520 void CreateControllerAndTarget() { | 671 void CreateControllerAndTarget() { |
(...skipping 943 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1464 static_cast<MockSyntheticTapMouseTarget*>(target_); | 1615 static_cast<MockSyntheticTapMouseTarget*>(target_); |
1465 EXPECT_EQ(1, num_success_); | 1616 EXPECT_EQ(1, num_success_); |
1466 EXPECT_EQ(0, num_failure_); | 1617 EXPECT_EQ(0, num_failure_); |
1467 EXPECT_TRUE(tap_target->GestureFinished()); | 1618 EXPECT_TRUE(tap_target->GestureFinished()); |
1468 EXPECT_EQ(tap_target->position(), params.position); | 1619 EXPECT_EQ(tap_target->position(), params.position); |
1469 EXPECT_EQ(tap_target->GetDuration().InMilliseconds(), params.duration_ms); | 1620 EXPECT_EQ(tap_target->GetDuration().InMilliseconds(), params.duration_ms); |
1470 EXPECT_GE(GetTotalTime(), | 1621 EXPECT_GE(GetTotalTime(), |
1471 base::TimeDelta::FromMilliseconds(params.duration_ms)); | 1622 base::TimeDelta::FromMilliseconds(params.duration_ms)); |
1472 } | 1623 } |
1473 | 1624 |
1625 TEST_F(SyntheticGestureControllerTest, PointerTouchAction) { | |
1626 CreateControllerAndTarget<MockSyntheticPointerTouchActionTarget>(); | |
1627 | |
1628 // First, send two touch presses for finger 0 and finger 1. | |
1629 SyntheticPointerActionListParams::ParamList param_list; | |
1630 SyntheticPointerActionParams param0 = SyntheticPointerActionParams( | |
1631 SyntheticPointerActionParams::PointerActionType::PRESS); | |
1632 SyntheticPointerActionParams param1 = SyntheticPointerActionParams( | |
1633 SyntheticPointerActionParams::PointerActionType::PRESS); | |
1634 param0.set_position(gfx::PointF(54, 89)); | |
1635 param0.set_index(0); | |
1636 param1.set_position(gfx::PointF(79, 132)); | |
1637 param1.set_index(1); | |
1638 param_list.push_back(param0); | |
1639 param_list.push_back(param1); | |
1640 SyntheticPointerActionListParams params(param_list); | |
1641 params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT; | |
1642 std::unique_ptr<SyntheticPointerAction> gesture( | |
1643 new SyntheticPointerAction(params)); | |
1644 QueueSyntheticGesture(std::move(gesture)); | |
1645 FlushInputUntilComplete(); | |
1646 | |
1647 MockSyntheticPointerTouchActionTarget* pointer_touch_target = | |
1648 static_cast<MockSyntheticPointerTouchActionTarget*>(target_); | |
1649 EXPECT_EQ(1, num_success_); | |
1650 EXPECT_EQ(0, num_failure_); | |
1651 EXPECT_EQ(pointer_touch_target->actions_dispatched_times(), 1); | |
1652 EXPECT_TRUE(pointer_touch_target->SyntheticTouchActionListDispatchedCorrectly( | |
1653 param_list)); | |
1654 | |
1655 // Second, send a touch release for finger 0, a touch move for finger 1. | |
1656 param0.set_pointer_action_type( | |
1657 SyntheticPointerActionParams::PointerActionType::RELEASE); | |
1658 param1.set_pointer_action_type( | |
1659 SyntheticPointerActionParams::PointerActionType::MOVE); | |
1660 param1.set_position(gfx::PointF(183, 239)); | |
1661 param_list.clear(); | |
1662 param_list.push_back(param0); | |
1663 param_list.push_back(param1); | |
1664 params.PushPointerActionParamsList(param_list); | |
1665 gesture.reset(new SyntheticPointerAction(params)); | |
1666 QueueSyntheticGesture(std::move(gesture)); | |
1667 pointer_touch_target->reset_actions_dispatched_times(); | |
1668 FlushInputUntilComplete(); | |
1669 | |
1670 EXPECT_EQ(2, num_success_); | |
1671 EXPECT_EQ(0, num_failure_); | |
1672 EXPECT_EQ(pointer_touch_target->actions_dispatched_times(), 2); | |
1673 EXPECT_TRUE(pointer_touch_target->SyntheticTouchActionListDispatchedCorrectly( | |
1674 param_list)); | |
1675 | |
1676 // Third, send a touch release for finger 1. | |
1677 param1.set_pointer_action_type( | |
1678 SyntheticPointerActionParams::PointerActionType::RELEASE); | |
1679 param_list.clear(); | |
1680 param_list.push_back(param1); | |
1681 params.PushPointerActionParamsList(param_list); | |
1682 gesture.reset(new SyntheticPointerAction(params)); | |
1683 QueueSyntheticGesture(std::move(gesture)); | |
1684 pointer_touch_target->reset_actions_dispatched_times(); | |
1685 FlushInputUntilComplete(); | |
1686 | |
1687 EXPECT_EQ(3, num_success_); | |
1688 EXPECT_EQ(0, num_failure_); | |
1689 EXPECT_EQ(pointer_touch_target->actions_dispatched_times(), 3); | |
1690 EXPECT_TRUE(pointer_touch_target->SyntheticTouchActionListDispatchedCorrectly( | |
1691 param_list)); | |
1692 } | |
1693 | |
1694 TEST_F(SyntheticGestureControllerTest, PointerMouseAction) { | |
1695 CreateControllerAndTarget<MockSyntheticPointerMouseActionTarget>(); | |
1696 | |
1697 // First, send a mouse move. | |
1698 SyntheticPointerActionListParams::ParamList param_list; | |
1699 SyntheticPointerActionParams param = SyntheticPointerActionParams( | |
1700 SyntheticPointerActionParams::PointerActionType::MOVE); | |
1701 | |
1702 param.set_position(gfx::PointF(54, 89)); | |
1703 SyntheticPointerActionListParams params; | |
1704 params.PushPointerActionParams(param); | |
1705 params.gesture_source_type = SyntheticGestureParams::MOUSE_INPUT; | |
1706 std::unique_ptr<SyntheticPointerAction> gesture( | |
1707 new SyntheticPointerAction(params)); | |
1708 QueueSyntheticGesture(std::move(gesture)); | |
1709 FlushInputUntilComplete(); | |
1710 | |
1711 MockSyntheticPointerMouseActionTarget* pointer_mouse_target = | |
1712 static_cast<MockSyntheticPointerMouseActionTarget*>(target_); | |
1713 EXPECT_EQ(1, num_success_); | |
1714 EXPECT_EQ(0, num_failure_); | |
1715 EXPECT_EQ(pointer_mouse_target->actions_dispatched_times(), 1); | |
1716 EXPECT_TRUE( | |
1717 pointer_mouse_target->SyntheticMouseActionDispatchedCorrectly(param, 0)); | |
1718 | |
1719 // Second, send a mouse press. | |
1720 param.set_pointer_action_type( | |
1721 SyntheticPointerActionParams::PointerActionType::PRESS); | |
1722 param.set_position(gfx::PointF(183, 239)); | |
1723 params.PushPointerActionParams(param); | |
1724 gesture.reset(new SyntheticPointerAction(params)); | |
1725 QueueSyntheticGesture(std::move(gesture)); | |
1726 pointer_mouse_target->reset_actions_dispatched_times(); | |
1727 FlushInputUntilComplete(); | |
1728 | |
1729 EXPECT_EQ(2, num_success_); | |
1730 EXPECT_EQ(0, num_failure_); | |
1731 EXPECT_EQ(pointer_mouse_target->actions_dispatched_times(), 2); | |
1732 EXPECT_TRUE( | |
1733 pointer_mouse_target->SyntheticMouseActionDispatchedCorrectly(param, 1)); | |
1734 | |
1735 // Third, send a mouse move. | |
1736 param.set_pointer_action_type( | |
1737 SyntheticPointerActionParams::PointerActionType::MOVE); | |
1738 param.set_position(gfx::PointF(254, 279)); | |
1739 params.PushPointerActionParams(param); | |
1740 gesture.reset(new SyntheticPointerAction(params)); | |
1741 QueueSyntheticGesture(std::move(gesture)); | |
1742 pointer_mouse_target->reset_actions_dispatched_times(); | |
1743 FlushInputUntilComplete(); | |
1744 | |
1745 EXPECT_EQ(3, num_success_); | |
1746 EXPECT_EQ(0, num_failure_); | |
1747 EXPECT_EQ(pointer_mouse_target->actions_dispatched_times(), 3); | |
1748 EXPECT_TRUE( | |
1749 pointer_mouse_target->SyntheticMouseActionDispatchedCorrectly(param, 1)); | |
1750 | |
1751 // Fourth, send a mouse release. | |
1752 param.set_pointer_action_type( | |
1753 SyntheticPointerActionParams::PointerActionType::RELEASE); | |
1754 params.PushPointerActionParams(param); | |
1755 gesture.reset(new SyntheticPointerAction(params)); | |
1756 QueueSyntheticGesture(std::move(gesture)); | |
1757 pointer_mouse_target->reset_actions_dispatched_times(); | |
1758 FlushInputUntilComplete(); | |
1759 | |
1760 EXPECT_EQ(4, num_success_); | |
1761 EXPECT_EQ(0, num_failure_); | |
1762 EXPECT_EQ(pointer_mouse_target->actions_dispatched_times(), 4); | |
1763 EXPECT_TRUE( | |
1764 pointer_mouse_target->SyntheticMouseActionDispatchedCorrectly(param, 1)); | |
1765 } | |
1766 | |
1474 } // namespace | 1767 } // namespace |
1475 | 1768 |
1476 } // namespace content | 1769 } // namespace content |
OLD | NEW |