Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / content / browser / renderer_host / input / touch_emulator.cc
index 2ee0247..c844203 100644 (file)
@@ -7,9 +7,9 @@
 #include "content/browser/renderer_host/input/motion_event_web.h"
 #include "content/browser/renderer_host/input/web_input_event_util.h"
 #include "content/common/input/web_touch_event_traits.h"
+#include "content/grit/content_resources.h"
 #include "content/public/common/content_client.h"
 #include "content/public/common/content_switches.h"
-#include "grit/content_resources.h"
 #include "third_party/WebKit/public/platform/WebCursorInfo.h"
 #include "ui/events/gesture_detection/gesture_config_helper.h"
 #include "ui/gfx/image/image.h"
@@ -47,14 +47,15 @@ TouchEmulator::TouchEmulator(TouchEmulatorClient* client)
     : client_(client),
       gesture_provider_(GetGestureProviderConfig(), this),
       enabled_(false),
-      allow_pinch_(false) {
+      emulated_stream_active_sequence_count_(0),
+      native_stream_active_sequence_count_(0) {
   DCHECK(client_);
   ResetState();
 
   bool use_2x = gfx::Screen::GetNativeScreen()->
       GetPrimaryDisplay().device_scale_factor() > 1.5f;
   float cursor_scale_factor = use_2x ? 2.f : 1.f;
-  InitCursorFromResource(&touch_cursor_,
+  cursor_size_ = InitCursorFromResource(&touch_cursor_,
       cursor_scale_factor,
       use_2x ? IDR_DEVTOOLS_TOUCH_CURSOR_ICON_2X :
           IDR_DEVTOOLS_TOUCH_CURSOR_ICON);
@@ -85,18 +86,16 @@ void TouchEmulator::ResetState() {
   last_mouse_move_timestamp_ = 0;
   mouse_pressed_ = false;
   shift_pressed_ = false;
-  touch_active_ = false;
   suppress_next_fling_cancel_ = false;
   pinch_scale_ = 1.f;
   pinch_gesture_active_ = false;
 }
 
-void TouchEmulator::Enable(bool allow_pinch) {
+void TouchEmulator::Enable() {
   if (!enabled_) {
     enabled_ = true;
     ResetState();
   }
-  allow_pinch_ = allow_pinch;
   UpdateCursor();
 }
 
@@ -109,7 +108,7 @@ void TouchEmulator::Disable() {
   CancelTouch();
 }
 
-void TouchEmulator::InitCursorFromResource(
+gfx::SizeF TouchEmulator::InitCursorFromResource(
     WebCursor* cursor, float scale, int resource_id) {
   gfx::Image& cursor_image =
       content::GetContentClient()->GetNativeImageNamed(resource_id);
@@ -124,6 +123,7 @@ void TouchEmulator::InitCursorFromResource(
 #endif
 
   cursor->InitFromCursorInfo(cursor_info);
+  return gfx::ScaleSize(cursor_image.Size(), 1.f / scale);
 }
 
 bool TouchEmulator::HandleMouseEvent(const WebMouseEvent& mouse_event) {
@@ -159,7 +159,7 @@ bool TouchEmulator::HandleMouseEvent(const WebMouseEvent& mouse_event) {
 
   if (FillTouchEventAndPoint(mouse_event) &&
       gesture_provider_.OnTouchEvent(MotionEventWeb(touch_event_))) {
-    client_->ForwardTouchEvent(touch_event_);
+    ForwardTouchEventToClient();
   }
 
   // Do not pass mouse events to the renderer.
@@ -171,7 +171,7 @@ bool TouchEmulator::HandleMouseWheelEvent(const WebMouseWheelEvent& event) {
     return false;
 
   // Send mouse wheel for easy scrolling when there is no active touch.
-  return touch_active_;
+  return emulated_stream_active_sequence_count_ > 0;
 }
 
 bool TouchEmulator::HandleKeyboardEvent(const WebKeyboardEvent& event) {
@@ -197,11 +197,59 @@ bool TouchEmulator::HandleKeyboardEvent(const WebKeyboardEvent& event) {
   return false;
 }
 
-bool TouchEmulator::HandleTouchEventAck(InputEventAckState ack_result) {
-  const bool event_consumed = ack_result == INPUT_EVENT_ACK_STATE_CONSUMED;
-  gesture_provider_.OnTouchEventAck(event_consumed);
-  // TODO(dgozman): Disable emulation when real touch events are available.
-  return true;
+bool TouchEmulator::HandleTouchEvent(const blink::WebTouchEvent& event) {
+  // Block native event when emulated touch stream is active.
+  if (emulated_stream_active_sequence_count_)
+    return true;
+
+  bool is_sequence_start = WebTouchEventTraits::IsTouchSequenceStart(event);
+  // Do not allow middle-sequence event to pass through, if start was blocked.
+  if (!native_stream_active_sequence_count_ && !is_sequence_start)
+    return true;
+
+  if (is_sequence_start)
+    native_stream_active_sequence_count_++;
+  return false;
+}
+
+void TouchEmulator::ForwardTouchEventToClient() {
+  const bool event_consumed = true;
+  // Block emulated event when emulated native stream is active.
+  if (native_stream_active_sequence_count_) {
+    gesture_provider_.OnTouchEventAck(event_consumed);
+    return;
+  }
+
+  bool is_sequence_start =
+      WebTouchEventTraits::IsTouchSequenceStart(touch_event_);
+  // Do not allow middle-sequence event to pass through, if start was blocked.
+  if (!emulated_stream_active_sequence_count_ && !is_sequence_start) {
+    gesture_provider_.OnTouchEventAck(event_consumed);
+    return;
+  }
+
+  if (is_sequence_start)
+    emulated_stream_active_sequence_count_++;
+  client_->ForwardEmulatedTouchEvent(touch_event_);
+}
+
+bool TouchEmulator::HandleTouchEventAck(
+    const blink::WebTouchEvent& event, InputEventAckState ack_result) {
+  bool is_sequence_end = WebTouchEventTraits::IsTouchSequenceEnd(event);
+  if (emulated_stream_active_sequence_count_) {
+    if (is_sequence_end)
+      emulated_stream_active_sequence_count_--;
+
+    const bool event_consumed = ack_result == INPUT_EVENT_ACK_STATE_CONSUMED;
+    gesture_provider_.OnTouchEventAck(event_consumed);
+    return true;
+  }
+
+  // We may have not seen native touch sequence start (when created in the
+  // middle of a sequence), so don't decrement sequence count below zero.
+  if (is_sequence_end && native_stream_active_sequence_count_)
+    native_stream_active_sequence_count_--;
+  return false;
 }
 
 void TouchEmulator::OnGestureEvent(const ui::GestureEventData& gesture) {
@@ -271,16 +319,16 @@ void TouchEmulator::OnGestureEvent(const ui::GestureEventData& gesture) {
 }
 
 void TouchEmulator::CancelTouch() {
-  if (!touch_active_)
+  if (!emulated_stream_active_sequence_count_)
     return;
 
   WebTouchEventTraits::ResetTypeAndTouchStates(
       WebInputEvent::TouchCancel,
       (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(),
       &touch_event_);
-  touch_active_ = false;
-  if (gesture_provider_.OnTouchEvent(MotionEventWeb(touch_event_)))
-    client_->ForwardTouchEvent(touch_event_);
+  if (gesture_provider_.GetCurrentDownEvent() &&
+      gesture_provider_.OnTouchEvent(MotionEventWeb(touch_event_)))
+    ForwardTouchEventToClient();
 }
 
 void TouchEmulator::UpdateCursor() {
@@ -356,14 +404,12 @@ bool TouchEmulator::FillTouchEventAndPoint(const WebMouseEvent& mouse_event) {
   switch (mouse_event.type) {
     case WebInputEvent::MouseDown:
       eventType = WebInputEvent::TouchStart;
-      touch_active_ = true;
       break;
     case WebInputEvent::MouseMove:
       eventType = WebInputEvent::TouchMove;
       break;
     case WebInputEvent::MouseUp:
       eventType = WebInputEvent::TouchEnd;
-      touch_active_ = false;
       break;
     default:
       eventType = WebInputEvent::Undefined;
@@ -376,7 +422,8 @@ bool TouchEmulator::FillTouchEventAndPoint(const WebMouseEvent& mouse_event) {
 
   WebTouchPoint& point = touch_event_.touches[0];
   point.id = 0;
-  point.radiusX = point.radiusY = 1.f;
+  point.radiusX = 0.5f * cursor_size_.width();
+  point.radiusY = 0.5f * cursor_size_.height();
   point.force = 1.f;
   point.rotationAngle = 0.f;
   point.position.x = mouse_event.x;
@@ -388,7 +435,7 @@ bool TouchEmulator::FillTouchEventAndPoint(const WebMouseEvent& mouse_event) {
 }
 
 bool TouchEmulator::InPinchGestureMode() const {
-  return shift_pressed_ && allow_pinch_;
+  return shift_pressed_;
 }
 
 }  // namespace content