1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "content/browser/renderer_host/input/synthetic_touch_driver.h"
6 
7 #include "content/browser/renderer_host/input/synthetic_gesture_target.h"
8 
9 namespace content {
10 
SyntheticTouchDriver()11 SyntheticTouchDriver::SyntheticTouchDriver() {}
12 
SyntheticTouchDriver(SyntheticWebTouchEvent touch_event)13 SyntheticTouchDriver::SyntheticTouchDriver(SyntheticWebTouchEvent touch_event)
14     : touch_event_(touch_event) {}
15 
~SyntheticTouchDriver()16 SyntheticTouchDriver::~SyntheticTouchDriver() {}
17 
DispatchEvent(SyntheticGestureTarget * target,const base::TimeTicks & timestamp)18 void SyntheticTouchDriver::DispatchEvent(SyntheticGestureTarget* target,
19                                          const base::TimeTicks& timestamp) {
20   touch_event_.SetTimeStamp(timestamp);
21   if (touch_event_.GetType() != blink::WebInputEvent::kUndefined)
22     target->DispatchInputEventToPlatform(touch_event_);
23   touch_event_.ResetPoints();
24   ResetPointerIdIndexMap();
25 }
26 
Press(float x,float y,int index,SyntheticPointerActionParams::Button button,int key_modifiers,float width,float height,float rotation_angle,float force,const base::TimeTicks & timestamp)27 void SyntheticTouchDriver::Press(float x,
28                                  float y,
29                                  int index,
30                                  SyntheticPointerActionParams::Button button,
31                                  int key_modifiers,
32                                  float width,
33                                  float height,
34                                  float rotation_angle,
35                                  float force,
36                                  const base::TimeTicks& timestamp) {
37   DCHECK_GE(index, 0);
38   DCHECK(pointer_id_map_.find(index) == pointer_id_map_.end());
39   int touch_index = touch_event_.PressPoint(x, y, width / 2.f, height / 2.f,
40                                             rotation_angle, force);
41   touch_event_.touches[touch_index].id = index;
42   pointer_id_map_[index] = touch_index;
43   touch_event_.SetModifiers(key_modifiers);
44 }
45 
Move(float x,float y,int index,int key_modifiers,float width,float height,float rotation_angle,float force)46 void SyntheticTouchDriver::Move(float x,
47                                 float y,
48                                 int index,
49                                 int key_modifiers,
50                                 float width,
51                                 float height,
52                                 float rotation_angle,
53                                 float force) {
54   DCHECK_GE(index, 0);
55   DCHECK(pointer_id_map_.find(index) != pointer_id_map_.end());
56   touch_event_.MovePoint(pointer_id_map_[index], x, y, width / 2.f,
57                          height / 2.f, rotation_angle, force);
58   touch_event_.SetModifiers(key_modifiers);
59 }
60 
Release(int index,SyntheticPointerActionParams::Button button,int key_modifiers)61 void SyntheticTouchDriver::Release(int index,
62                                    SyntheticPointerActionParams::Button button,
63                                    int key_modifiers) {
64   DCHECK_GE(index, 0);
65   DCHECK(pointer_id_map_.find(index) != pointer_id_map_.end());
66   touch_event_.ReleasePoint(pointer_id_map_[index]);
67   touch_event_.SetModifiers(key_modifiers);
68   pointer_id_map_.erase(index);
69 }
70 
Cancel(int index,SyntheticPointerActionParams::Button button,int key_modifiers)71 void SyntheticTouchDriver::Cancel(int index,
72                                   SyntheticPointerActionParams::Button button,
73                                   int key_modifiers) {
74   DCHECK_GE(index, 0);
75   DCHECK(pointer_id_map_.find(index) != pointer_id_map_.end());
76   touch_event_.CancelPoint(pointer_id_map_[index]);
77   touch_event_.SetModifiers(key_modifiers);
78   touch_event_.dispatch_type = blink::WebInputEvent::kEventNonBlocking;
79   pointer_id_map_.erase(index);
80 }
81 
Leave(int index)82 void SyntheticTouchDriver::Leave(int index) {
83   NOTIMPLEMENTED();
84 }
85 
UserInputCheck(const SyntheticPointerActionParams & params) const86 bool SyntheticTouchDriver::UserInputCheck(
87     const SyntheticPointerActionParams& params) const {
88   if (params.pointer_action_type() ==
89       SyntheticPointerActionParams::PointerActionType::NOT_INITIALIZED) {
90     return false;
91   }
92 
93   if (params.pointer_action_type() ==
94           SyntheticPointerActionParams::PointerActionType::PRESS &&
95       pointer_id_map_.find(params.pointer_id()) != pointer_id_map_.end()) {
96     return false;
97   }
98 
99   if (params.pointer_action_type() ==
100           SyntheticPointerActionParams::PointerActionType::MOVE &&
101       pointer_id_map_.find(params.pointer_id()) == pointer_id_map_.end()) {
102     return false;
103   }
104 
105   if (params.pointer_action_type() ==
106           SyntheticPointerActionParams::PointerActionType::RELEASE &&
107       pointer_id_map_.find(params.pointer_id()) == pointer_id_map_.end()) {
108     return false;
109   }
110 
111   return true;
112 }
113 
ResetPointerIdIndexMap()114 void SyntheticTouchDriver::ResetPointerIdIndexMap() {
115   unsigned free_index = 0;
116   for (unsigned int i = 0; i < blink::WebTouchEvent::kTouchesLengthCap; ++i) {
117     if (free_index >= touch_event_.touches_length)
118       break;
119     if (touch_event_.touches[i].state !=
120         blink::WebTouchPoint::kStateUndefined) {
121       touch_event_.touches[free_index] = touch_event_.touches[i];
122       if (free_index != i)
123         touch_event_.touches[i] = blink::WebTouchPoint();
124       int pointer_id = GetIndexFromMap(i);
125       pointer_id_map_[pointer_id] = free_index;
126       free_index++;
127     }
128   }
129 }
130 
GetIndexFromMap(int value) const131 int SyntheticTouchDriver::GetIndexFromMap(int value) const {
132   PointerIdIndexMap::const_iterator it;
133   for (it = pointer_id_map_.begin(); it != pointer_id_map_.end(); ++it) {
134     if (it->second == value) {
135       return it->first;
136     }
137   }
138   NOTREACHED() << "Failed to find the value.";
139   return -1;
140 }
141 
142 }  // namespace content
143