summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreero.hakkinen <eero.hakkinen@intel.com>2015-11-02 15:50:11 -0800
committerCommit bot <commit-bot@chromium.org>2015-11-02 23:50:56 +0000
commitb39a02032b11742cc467f43026a77a0aba33d5c1 (patch)
treeff8055dfdbac6b638bc0c8c1df74de473bb809f5
parentf10f3900fca497febec0cac5ef82a3337c041705 (diff)
downloadchromium_src-b39a02032b11742cc467f43026a77a0aba33d5c1.zip
chromium_src-b39a02032b11742cc467f43026a77a0aba33d5c1.tar.gz
chromium_src-b39a02032b11742cc467f43026a77a0aba33d5c1.tar.bz2
Pass MotionEvent tilt angles to Blink on Android.
This extends event handlers to pass tilt angles from Android MotionEvent to Blink touch points, so that on the Blink side, PointerEvent tiltX and tiltY can be filled with real tilt angles. This CL is a part of a patch series: 1. https://codereview.chromium.org/1253183005/ for new WebPointerProperties fields 2. https://codereview.chromium.org/1260693003/ for eventSender web pointer property support 3. https://codereview.chromium.org/1192563002/ for handling tilt in Blink event handlers 4. https://codereview.chromium.org/1417803002/ (this) This CL is based on the abandoned CL at https://codereview.chromium.org/1187273004/ BUG=514360 Review URL: https://codereview.chromium.org/1417803002 Cr-Commit-Position: refs/heads/master@{#357471}
-rw-r--r--AUTHORS1
-rw-r--r--content/browser/android/content_view_core_impl.cc4
-rw-r--r--content/browser/android/content_view_core_impl.h2
-rw-r--r--content/browser/renderer_host/input/motion_event_android.cc14
-rw-r--r--content/browser/renderer_host/input/motion_event_android.h4
-rw-r--r--content/browser/renderer_host/input/motion_event_android_unittest.cc26
-rw-r--r--content/browser/renderer_host/input/motion_event_web.cc50
-rw-r--r--content/browser/renderer_host/input/motion_event_web.h4
-rw-r--r--content/browser/renderer_host/input/motion_event_web_unittest.cc78
-rw-r--r--content/browser/renderer_host/input/touch_emulator.cc2
-rw-r--r--content/browser/renderer_host/input/touch_event_queue.cc4
-rw-r--r--content/browser/renderer_host/input/web_input_event_util_unittest.cc67
-rw-r--r--content/common/input/synthetic_web_input_event_builders.cc1
-rw-r--r--content/common/input/web_input_event_traits.cc7
-rw-r--r--content/content_tests.gypi1
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java3
-rw-r--r--ui/events/blink/blink_event_util.cc15
-rw-r--r--ui/events/gesture_detection/motion_event.h2
-rw-r--r--ui/events/gesture_detection/motion_event_buffer_unittest.cc1
-rw-r--r--ui/events/gesture_detection/motion_event_generic.cc7
-rw-r--r--ui/events/gesture_detection/motion_event_generic.h2
-rw-r--r--ui/events/test/motion_event_test_utils.cc1
22 files changed, 246 insertions, 50 deletions
diff --git a/AUTHORS b/AUTHORS
index 062bd88..afbb3aa 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -159,6 +159,7 @@ Eduardo Lima (Etrunko) <eblima@gmail.com>
Eduardo Lima (Etrunko) <eduardo.lima@intel.com>
Edward Baker <edward.baker@intel.com>
Edward Crossman <tedoc2000@gmail.com>
+Eero Häkkinen <eero.hakkinen@intel.com>
Eero Häkkinen <e.hakkinen@samsung.com>
Egor Starkov <egor.starkov@samsung.com>
Ehsan Akhgari <ehsan.akhgari@gmail.com>
diff --git a/content/browser/android/content_view_core_impl.cc b/content/browser/android/content_view_core_impl.cc
index 6046ba2..18b8722 100644
--- a/content/browser/android/content_view_core_impl.cc
+++ b/content/browser/android/content_view_core_impl.cc
@@ -879,6 +879,8 @@ jboolean ContentViewCoreImpl::OnTouchEvent(JNIEnv* env,
jfloat touch_minor_1,
jfloat orientation_0,
jfloat orientation_1,
+ jfloat tilt_0,
+ jfloat tilt_1,
jfloat raw_pos_x,
jfloat raw_pos_y,
jint android_tool_type_0,
@@ -897,6 +899,7 @@ jboolean ContentViewCoreImpl::OnTouchEvent(JNIEnv* env,
touch_major_0,
touch_minor_0,
orientation_0,
+ tilt_0,
android_tool_type_0);
MotionEventAndroid::Pointer pointer1(pointer_id_1,
pos_x_1,
@@ -904,6 +907,7 @@ jboolean ContentViewCoreImpl::OnTouchEvent(JNIEnv* env,
touch_major_1,
touch_minor_1,
orientation_1,
+ tilt_1,
android_tool_type_1);
MotionEventAndroid event(1.f / dpi_scale(),
env,
diff --git a/content/browser/android/content_view_core_impl.h b/content/browser/android/content_view_core_impl.h
index 4fd7ccb..55157a1 100644
--- a/content/browser/android/content_view_core_impl.h
+++ b/content/browser/android/content_view_core_impl.h
@@ -105,6 +105,8 @@ class ContentViewCoreImpl : public ContentViewCore,
jfloat touch_minor_1,
jfloat orientation_0,
jfloat orientation_1,
+ jfloat tilt_0,
+ jfloat tilt_1,
jfloat raw_pos_x,
jfloat raw_pos_y,
jint android_tool_type_0,
diff --git a/content/browser/renderer_host/input/motion_event_android.cc b/content/browser/renderer_host/input/motion_event_android.cc
index 4d30a3f..6392e90 100644
--- a/content/browser/renderer_host/input/motion_event_android.cc
+++ b/content/browser/renderer_host/input/motion_event_android.cc
@@ -129,6 +129,7 @@ MotionEventAndroid::Pointer::Pointer(jint id,
jfloat touch_major_pixels,
jfloat touch_minor_pixels,
jfloat orientation_rad,
+ jfloat tilt_rad,
jint tool_type)
: id(id),
pos_x_pixels(pos_x_pixels),
@@ -136,6 +137,7 @@ MotionEventAndroid::Pointer::Pointer(jint id,
touch_major_pixels(touch_major_pixels),
touch_minor_pixels(touch_minor_pixels),
orientation_rad(orientation_rad),
+ tilt_rad(tilt_rad),
tool_type(tool_type) {
}
@@ -144,6 +146,7 @@ MotionEventAndroid::CachedPointer::CachedPointer()
touch_major(0),
touch_minor(0),
orientation(0),
+ tilt(0),
tool_type(TOOL_TYPE_UNKNOWN) {
}
@@ -273,6 +276,16 @@ float MotionEventAndroid::GetPressure(size_t pointer_index) const {
AttachCurrentThread(), event_.obj(), pointer_index);
}
+float MotionEventAndroid::GetTilt(size_t pointer_index) const {
+ DCHECK_LT(pointer_index, cached_pointer_count_);
+ if (pointer_index < MAX_POINTERS_TO_CACHE)
+ return cached_pointers_[pointer_index].tilt;
+ if (!event_.obj())
+ return 0.f;
+ return ToValidFloat(Java_MotionEvent_getAxisValueF_I_I(
+ AttachCurrentThread(), event_.obj(), AXIS_TILT, pointer_index));
+}
+
base::TimeTicks MotionEventAndroid::GetEventTime() const {
return cached_time_;
}
@@ -336,6 +349,7 @@ MotionEventAndroid::CachedPointer MotionEventAndroid::FromAndroidPointer(
result.touch_major = ToDips(pointer.touch_major_pixels);
result.touch_minor = ToDips(pointer.touch_minor_pixels);
result.orientation = ToValidFloat(pointer.orientation_rad);
+ result.tilt = ToValidFloat(pointer.tilt_rad);
result.tool_type = FromAndroidToolType(pointer.tool_type);
return result;
}
diff --git a/content/browser/renderer_host/input/motion_event_android.h b/content/browser/renderer_host/input/motion_event_android.h
index bf4dfed..d581ce0 100644
--- a/content/browser/renderer_host/input/motion_event_android.h
+++ b/content/browser/renderer_host/input/motion_event_android.h
@@ -29,6 +29,7 @@ class CONTENT_EXPORT MotionEventAndroid : public ui::MotionEvent {
jfloat touch_major_pixels,
jfloat touch_minor_pixels,
jfloat orientation_rad,
+ jfloat tilt_rad,
jint tool_type);
jint id;
jfloat pos_x_pixels;
@@ -36,6 +37,7 @@ class CONTENT_EXPORT MotionEventAndroid : public ui::MotionEvent {
jfloat touch_major_pixels;
jfloat touch_minor_pixels;
jfloat orientation_rad;
+ jfloat tilt_rad;
jint tool_type;
};
@@ -71,6 +73,7 @@ class CONTENT_EXPORT MotionEventAndroid : public ui::MotionEvent {
float GetTouchMinor(size_t pointer_index) const override;
float GetOrientation(size_t pointer_index) const override;
float GetPressure(size_t pointer_index) const override;
+ float GetTilt(size_t pointer_index) const override;
base::TimeTicks GetEventTime() const override;
size_t GetHistorySize() const override;
base::TimeTicks GetHistoricalEventTime(
@@ -120,6 +123,7 @@ class CONTENT_EXPORT MotionEventAndroid : public ui::MotionEvent {
float touch_major;
float touch_minor;
float orientation;
+ float tilt;
ToolType tool_type;
} cached_pointers_[MAX_POINTERS_TO_CACHE];
diff --git a/content/browser/renderer_host/input/motion_event_android_unittest.cc b/content/browser/renderer_host/input/motion_event_android_unittest.cc
index 9a33b31..c888aca 100644
--- a/content/browser/renderer_host/input/motion_event_android_unittest.cc
+++ b/content/browser/renderer_host/input/motion_event_android_unittest.cc
@@ -39,9 +39,9 @@ TEST(MotionEventAndroidTest, Constructor) {
base::TimeTicks event_time =
base::TimeTicks() + base::TimeDelta::FromMilliseconds(event_time_ms);
MotionEventAndroid::Pointer p0(
- 1, 13.7f, -7.13f, 5.3f, 1.2f, 0.1f, kAndroidToolTypeFinger);
+ 1, 13.7f, -7.13f, 5.3f, 1.2f, 0.1f, 0.2f, kAndroidToolTypeFinger);
MotionEventAndroid::Pointer p1(
- 2, -13.7f, 7.13f, 3.5f, 12.1f, -0.1f, kAndroidToolTypeFinger);
+ 2, -13.7f, 7.13f, 3.5f, 12.1f, -0.1f, -0.4f, kAndroidToolTypeFinger);
float raw_offset = -3.f;
int pointer_count = 2;
int history_size = 0;
@@ -77,6 +77,8 @@ TEST(MotionEventAndroidTest, Constructor) {
EXPECT_EQ(p1.touch_minor_pixels * kPixToDip, event.GetTouchMinor(1));
EXPECT_EQ(p0.orientation_rad, event.GetOrientation(0));
EXPECT_EQ(p1.orientation_rad, event.GetOrientation(1));
+ EXPECT_EQ(p0.tilt_rad, event.GetTilt(0));
+ EXPECT_EQ(p1.tilt_rad, event.GetTilt(1));
EXPECT_EQ(p0.id, event.GetPointerId(0));
EXPECT_EQ(p1.id, event.GetPointerId(1));
EXPECT_EQ(MotionEvent::TOOL_TYPE_FINGER, event.GetToolType(0));
@@ -90,8 +92,8 @@ TEST(MotionEventAndroidTest, Constructor) {
TEST(MotionEventAndroidTest, Clone) {
const int pointer_count = 1;
MotionEventAndroid::Pointer p0(
- 1, 13.7f, -7.13f, 5.3f, 1.2f, 0.1f, kAndroidToolTypeFinger);
- MotionEventAndroid::Pointer p1(0, 0, 0, 0, 0, 0, 0);
+ 1, 13.7f, -7.13f, 5.3f, 1.2f, 0.1f, 0.2f, kAndroidToolTypeFinger);
+ MotionEventAndroid::Pointer p1(0, 0, 0, 0, 0, 0, 0, 0);
MotionEventAndroid event(kPixToDip,
base::android::AttachCurrentThread(),
nullptr,
@@ -115,8 +117,8 @@ TEST(MotionEventAndroidTest, Cancel) {
const int event_time_ms = 5;
const int pointer_count = 1;
MotionEventAndroid::Pointer p0(
- 1, 13.7f, -7.13f, 5.3f, 1.2f, 0.1f, kAndroidToolTypeFinger);
- MotionEventAndroid::Pointer p1(0, 0, 0, 0, 0, 0, 0);
+ 1, 13.7f, -7.13f, 5.3f, 1.2f, 0.1f, 0.2f, kAndroidToolTypeFinger);
+ MotionEventAndroid::Pointer p1(0, 0, 0, 0, 0, 0, 0, 0);
MotionEventAndroid event(kPixToDip,
base::android::AttachCurrentThread(),
nullptr,
@@ -148,8 +150,8 @@ TEST(MotionEventAndroidTest, InvalidOrientationsSanitized) {
int pointer_count = 2;
float orientation0 = 1e10f;
float orientation1 = std::numeric_limits<float>::quiet_NaN();
- MotionEventAndroid::Pointer p0(0, 0, 0, 0, 0, orientation0, 0);
- MotionEventAndroid::Pointer p1(1, 0, 0, 0, 0, orientation1, 0);
+ MotionEventAndroid::Pointer p0(0, 0, 0, 0, 0, orientation0, 0, 0);
+ MotionEventAndroid::Pointer p1(1, 0, 0, 0, 0, orientation1, 0, 0);
MotionEventAndroid event(kPixToDip,
base::android::AttachCurrentThread(),
nullptr,
@@ -172,8 +174,8 @@ TEST(MotionEventAndroidTest, InvalidOrientationsSanitized) {
TEST(MotionEventAndroidTest, NonEmptyHistoryForNonMoveEventsSanitized) {
int pointer_count = 1;
size_t history_size = 5;
- MotionEventAndroid::Pointer p0(0, 0, 0, 0, 0, 0, 0);
- MotionEventAndroid::Pointer p1(0, 0, 0, 0, 0, 0, 0);
+ MotionEventAndroid::Pointer p0(0, 0, 0, 0, 0, 0, 0, 0);
+ MotionEventAndroid::Pointer p1(0, 0, 0, 0, 0, 0, 0, 0);
MotionEventAndroid event(kPixToDip,
base::android::AttachCurrentThread(),
nullptr,
@@ -194,9 +196,9 @@ TEST(MotionEventAndroidTest, NonEmptyHistoryForNonMoveEventsSanitized) {
TEST(MotionEventAndroidTest, ActionIndexForPointerDown) {
MotionEventAndroid::Pointer p0(
- 1, 13.7f, -7.13f, 5.3f, 1.2f, 0.1f, kAndroidToolTypeFinger);
+ 1, 13.7f, -7.13f, 5.3f, 1.2f, 0.1f, 0.2f, kAndroidToolTypeFinger);
MotionEventAndroid::Pointer p1(
- 2, -13.7f, 7.13f, 3.5f, 12.1f, -0.1f, kAndroidToolTypeFinger);
+ 2, -13.7f, 7.13f, 3.5f, 12.1f, -0.1f, -0.4f, kAndroidToolTypeFinger);
int pointer_count = 2;
int history_size = 0;
int action_index = 1;
diff --git a/content/browser/renderer_host/input/motion_event_web.cc b/content/browser/renderer_host/input/motion_event_web.cc
index ddc3037..30f141b 100644
--- a/content/browser/renderer_host/input/motion_event_web.cc
+++ b/content/browser/renderer_host/input/motion_event_web.cc
@@ -130,26 +130,62 @@ float MotionEventWeb::GetTouchMinor(size_t pointer_index) const {
float MotionEventWeb::GetOrientation(size_t pointer_index) const {
DCHECK_LT(pointer_index, GetPointerCount());
- float rotation_angle_rad = event_.touches[pointer_index].rotationAngle
+ float orientation_rad = event_.touches[pointer_index].rotationAngle
* M_PI / 180.f;
- DCHECK(0 <= rotation_angle_rad && rotation_angle_rad <= M_PI_2)
+ DCHECK(0 <= orientation_rad && orientation_rad <= M_PI_2)
<< "Unexpected touch rotation angle";
- if (event_.touches[pointer_index].radiusX
- > event_.touches[pointer_index].radiusY) {
+ if (GetToolType(pointer_index) == TOOL_TYPE_STYLUS) {
+ const WebPointerProperties& pointer = event_.touches[pointer_index];
+
+ if (pointer.tiltY <= 0 && pointer.tiltX < 0) {
+ // Stylus is tilted to the left away from the user or straight
+ // to the left thus the orientation should be within [pi/2,pi).
+ orientation_rad += static_cast<float>(M_PI_2);
+ } else if (pointer.tiltY < 0 && pointer.tiltX >= 0) {
+ // Stylus is tilted to the right away from the user or straight away
+ // from the user thus the orientation should be within [-pi,-pi/2).
+ orientation_rad -= static_cast<float>(M_PI);
+ } else if (pointer.tiltY >= 0 && pointer.tiltX > 0) {
+ // Stylus is tilted to the right towards the user or straight
+ // to the right thus the orientation should be within [-pi/2,0).
+ orientation_rad -= static_cast<float>(M_PI_2);
+ }
+ } else if (event_.touches[pointer_index].radiusX
+ > event_.touches[pointer_index].radiusY) {
// The case radiusX == radiusY is omitted from here on purpose: for circles,
// we want to pass the angle (which could be any value in such cases but
- // always seem to be set to zero) unchanged.
- rotation_angle_rad -= (float) M_PI_2;
+ // always seems to be set to zero) unchanged.
+ orientation_rad -= static_cast<float>(M_PI_2);
}
- return rotation_angle_rad;
+ return orientation_rad;
}
float MotionEventWeb::GetPressure(size_t pointer_index) const {
return 0.f;
}
+float MotionEventWeb::GetTilt(size_t pointer_index) const {
+ DCHECK_LT(pointer_index, GetPointerCount());
+
+ if (GetToolType(pointer_index) != TOOL_TYPE_STYLUS)
+ return 0.f;
+
+ const WebPointerProperties& pointer = event_.touches[pointer_index];
+
+ float tilt_x_r = sin(pointer.tiltX * M_PI / 180.f);
+ float tilt_x_z = cos(pointer.tiltX * M_PI / 180.f);
+ float tilt_y_r = sin(pointer.tiltY * M_PI / 180.f);
+ float tilt_y_z = cos(pointer.tiltY * M_PI / 180.f);
+ float r_x = tilt_x_r * tilt_y_z;
+ float r_y = tilt_y_r * tilt_x_z;
+ float r = sqrt(r_x * r_x + r_y * r_y);
+ float z = tilt_x_z * tilt_y_z;
+
+ return atan2(r, z);
+}
+
base::TimeTicks MotionEventWeb::GetEventTime() const {
return base::TimeTicks() +
base::TimeDelta::FromMicroseconds(event_.timeStampSeconds *
diff --git a/content/browser/renderer_host/input/motion_event_web.h b/content/browser/renderer_host/input/motion_event_web.h
index 34e9541..1aac855 100644
--- a/content/browser/renderer_host/input/motion_event_web.h
+++ b/content/browser/renderer_host/input/motion_event_web.h
@@ -5,13 +5,14 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_MOTION_EVENT_WEB_H_
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_MOTION_EVENT_WEB_H_
+#include "content/common/content_export.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
#include "ui/events/gesture_detection/motion_event.h"
namespace content {
// Implementation of ui::MotionEvent wrapping a WebTouchEvent.
-class MotionEventWeb : public ui::MotionEvent {
+class CONTENT_EXPORT MotionEventWeb : public ui::MotionEvent {
public:
explicit MotionEventWeb(const blink::WebTouchEvent& event);
~MotionEventWeb() override;
@@ -30,6 +31,7 @@ class MotionEventWeb : public ui::MotionEvent {
float GetTouchMinor(size_t pointer_index) const override;
float GetOrientation(size_t pointer_index) const override;
float GetPressure(size_t pointer_index) const override;
+ float GetTilt(size_t pointer_index) const override;
base::TimeTicks GetEventTime() const override;
ToolType GetToolType(size_t pointer_index) const override;
int GetButtonState() const override;
diff --git a/content/browser/renderer_host/input/motion_event_web_unittest.cc b/content/browser/renderer_host/input/motion_event_web_unittest.cc
new file mode 100644
index 0000000..d126ea7
--- /dev/null
+++ b/content/browser/renderer_host/input/motion_event_web_unittest.cc
@@ -0,0 +1,78 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// MSVC++ requires this to be set before any other includes to get M_PI.
+#define _USE_MATH_DEFINES
+
+#include <cmath>
+
+#include "content/browser/renderer_host/input/motion_event_web.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/events/blink/blink_event_util.h"
+#include "ui/events/gesture_detection/motion_event_generic.h"
+#include "ui/events/test/motion_event_test_utils.h"
+
+using ui::MotionEvent;
+using ui::MotionEventGeneric;
+using ui::PointerProperties;
+
+namespace content {
+
+TEST(MotionEventWebTest, Constructor) {
+ const float pi = static_cast<float>(M_PI);
+ const float orientations[] = {
+ -pi, -2.f * pi / 3, -pi / 2, -pi / 3, 0.f, pi / 3, pi / 2, 2.f * pi / 3};
+ const float tilts[] = {0.f, pi / 4, pi / 3};
+ const MotionEvent::ToolType tool_types[] = {MotionEvent::TOOL_TYPE_FINGER,
+ MotionEvent::TOOL_TYPE_STYLUS,
+ MotionEvent::TOOL_TYPE_MOUSE};
+
+ base::TimeTicks event_time = base::TimeTicks::Now();
+ PointerProperties pp;
+ MotionEventGeneric generic_event(MotionEvent::ACTION_MOVE, event_time, pp);
+
+ for (MotionEvent::ToolType tool_type : tool_types) {
+ for (float orientation : orientations) {
+ for (float tilt : tilts) {
+ PointerProperties pp2;
+ pp2.orientation = orientation;
+ pp2.tilt = tilt;
+ pp2.tool_type = tool_type;
+ size_t pointer_index = generic_event.PushPointer(pp2);
+ EXPECT_GT(pointer_index, 0u);
+
+ blink::WebTouchEvent web_touch_event =
+ CreateWebTouchEventFromMotionEvent(generic_event, true);
+
+ MotionEventWeb event(web_touch_event);
+ EXPECT_EQ(tool_type, event.GetToolType(pointer_index));
+ if (tool_type == MotionEvent::TOOL_TYPE_STYLUS) {
+ // Web touch event touch point tilt plane angles are stored as ints,
+ // thus the tilt precision is 1 degree and the error should not be
+ // greater than 0.5 degrees.
+ EXPECT_NEAR(tilt, event.GetTilt(pointer_index), 0.5f * M_PI / 180.f)
+ << " orientation=" << orientation;
+ } else {
+ EXPECT_EQ(0.f, event.GetTilt(pointer_index));
+ }
+ if (tool_type == MotionEvent::TOOL_TYPE_STYLUS && tilt > 0.f) {
+ // Full stylus tilt orientation information survives above event
+ // conversions only if there is a non-zero stylus tilt angle.
+ // See: http://crbug.com/251330
+ EXPECT_NEAR(orientation, event.GetOrientation(pointer_index), 1e-4)
+ << " tilt=" << tilt;
+ } else {
+ // For non-stylus pointers and for styluses with a zero tilt angle,
+ // orientation quadrant information is lost.
+ EXPECT_NEAR(fmod(orientation + M_PI + 1e-4, M_PI_2) - 1e-4,
+ event.GetOrientation(pointer_index), 1e-4);
+ }
+
+ generic_event.RemovePointerAt(pointer_index);
+ }
+ }
+ }
+}
+
+} // namespace content
diff --git a/content/browser/renderer_host/input/touch_emulator.cc b/content/browser/renderer_host/input/touch_emulator.cc
index 460716d..e095b9d 100644
--- a/content/browser/renderer_host/input/touch_emulator.cc
+++ b/content/browser/renderer_host/input/touch_emulator.cc
@@ -446,6 +446,8 @@ void TouchEmulator::FillTouchEventAndPoint(const WebMouseEvent& mouse_event) {
point.screenPosition.x = mouse_event.globalX;
point.position.y = mouse_event.y;
point.screenPosition.y = mouse_event.globalY;
+ point.tiltX = 0;
+ point.tiltY = 0;
}
bool TouchEmulator::InPinchGestureMode() const {
diff --git a/content/browser/renderer_host/input/touch_event_queue.cc b/content/browser/renderer_host/input/touch_event_queue.cc
index 9de8093..8f3a6a9 100644
--- a/content/browser/renderer_host/input/touch_event_queue.cc
+++ b/content/browser/renderer_host/input/touch_event_queue.cc
@@ -56,7 +56,9 @@ bool HasPointChanged(const WebTouchPoint& point_1,
point_1.radiusX != point_2.radiusX ||
point_1.radiusY != point_2.radiusY ||
point_1.rotationAngle != point_2.rotationAngle ||
- point_1.force != point_2.force) {
+ point_1.force != point_2.force ||
+ point_1.tiltX != point_2.tiltX ||
+ point_1.tiltY != point_2.tiltY) {
return true;
}
return false;
diff --git a/content/browser/renderer_host/input/web_input_event_util_unittest.cc b/content/browser/renderer_host/input/web_input_event_util_unittest.cc
index 862d6c1..439e2c1 100644
--- a/content/browser/renderer_host/input/web_input_event_util_unittest.cc
+++ b/content/browser/renderer_host/input/web_input_event_util_unittest.cc
@@ -28,6 +28,10 @@ using ui::MotionEventGeneric;
namespace content {
TEST(WebInputEventUtilTest, MotionEventConversion) {
+
+ const MotionEvent::ToolType tool_types[] = {MotionEvent::TOOL_TYPE_FINGER,
+ MotionEvent::TOOL_TYPE_STYLUS,
+ MotionEvent::TOOL_TYPE_MOUSE};
ui::PointerProperties pointer(5, 10, 40);
pointer.id = 15;
pointer.raw_x = 20;
@@ -35,34 +39,45 @@ TEST(WebInputEventUtilTest, MotionEventConversion) {
pointer.pressure = 30;
pointer.touch_minor = 35;
pointer.orientation = static_cast<float>(-M_PI / 2);
- MotionEventGeneric event(
- MotionEvent::ACTION_DOWN, base::TimeTicks::Now(), pointer);
- event.set_flags(ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
- event.set_unique_event_id(123456U);
+ pointer.tilt = static_cast<float>(-M_PI / 3);
+ for (MotionEvent::ToolType tool_type : tool_types) {
+ pointer.tool_type = tool_type;
+ MotionEventGeneric event(
+ MotionEvent::ACTION_DOWN, base::TimeTicks::Now(), pointer);
+ event.set_flags(ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
+ event.set_unique_event_id(123456U);
- WebTouchEvent expected_event;
- expected_event.type = WebInputEvent::TouchStart;
- expected_event.touchesLength = 1;
- expected_event.timeStampSeconds =
- (event.GetEventTime() - base::TimeTicks()).InSecondsF();
- expected_event.modifiers = WebInputEvent::ShiftKey | WebInputEvent::AltKey;
- WebTouchPoint expected_pointer;
- expected_pointer.id = pointer.id;
- expected_pointer.state = WebTouchPoint::StatePressed;
- expected_pointer.position = blink::WebFloatPoint(pointer.x, pointer.y);
- expected_pointer.screenPosition =
- blink::WebFloatPoint(pointer.raw_x, pointer.raw_y);
- expected_pointer.radiusX = pointer.touch_major / 2.f;
- expected_pointer.radiusY = pointer.touch_minor / 2.f;
- expected_pointer.rotationAngle = 0.f;
- expected_pointer.force = pointer.pressure;
- expected_event.touches[0] = expected_pointer;
- expected_event.uniqueTouchEventId = 123456U;
+ WebTouchEvent expected_event;
+ expected_event.type = WebInputEvent::TouchStart;
+ expected_event.touchesLength = 1;
+ expected_event.timeStampSeconds =
+ (event.GetEventTime() - base::TimeTicks()).InSecondsF();
+ expected_event.modifiers = WebInputEvent::ShiftKey | WebInputEvent::AltKey;
+ WebTouchPoint expected_pointer;
+ expected_pointer.id = pointer.id;
+ expected_pointer.state = WebTouchPoint::StatePressed;
+ expected_pointer.position = blink::WebFloatPoint(pointer.x, pointer.y);
+ expected_pointer.screenPosition =
+ blink::WebFloatPoint(pointer.raw_x, pointer.raw_y);
+ expected_pointer.radiusX = pointer.touch_major / 2.f;
+ expected_pointer.radiusY = pointer.touch_minor / 2.f;
+ expected_pointer.rotationAngle = 0.f;
+ expected_pointer.force = pointer.pressure;
+ if (tool_type == MotionEvent::TOOL_TYPE_STYLUS) {
+ expected_pointer.tiltX = -60;
+ expected_pointer.tiltY = 0;
+ } else {
+ expected_pointer.tiltX = 0;
+ expected_pointer.tiltY = 0;
+ }
+ expected_event.touches[0] = expected_pointer;
+ expected_event.uniqueTouchEventId = 123456U;
- WebTouchEvent actual_event =
- ui::CreateWebTouchEventFromMotionEvent(event, false);
- EXPECT_EQ(WebInputEventTraits::ToString(expected_event),
- WebInputEventTraits::ToString(actual_event));
+ WebTouchEvent actual_event =
+ ui::CreateWebTouchEventFromMotionEvent(event, false);
+ EXPECT_EQ(WebInputEventTraits::ToString(expected_event),
+ WebInputEventTraits::ToString(actual_event));
+ }
}
TEST(WebInputEventUtilTest, ScrollUpdateConversion) {
diff --git a/content/common/input/synthetic_web_input_event_builders.cc b/content/common/input/synthetic_web_input_event_builders.cc
index d2f4c39..470951a 100644
--- a/content/common/input/synthetic_web_input_event_builders.cc
+++ b/content/common/input/synthetic_web_input_event_builders.cc
@@ -182,6 +182,7 @@ int SyntheticWebTouchEvent::PressPoint(float x, float y) {
point.radiusX = point.radiusY = 1.f;
point.rotationAngle = 1.f;
point.force = 1.f;
+ point.tiltX = point.tiltY = 0;
++touchesLength;
WebTouchEventTraits::ResetType(
WebInputEvent::TouchStart, timeStampSeconds, this);
diff --git a/content/common/input/web_input_event_traits.cc b/content/common/input/web_input_event_traits.cc
index 0a71bb8..2d98dcd 100644
--- a/content/common/input/web_input_event_traits.cc
+++ b/content/common/input/web_input_event_traits.cc
@@ -93,7 +93,8 @@ void ApppendEventDetails(const WebGestureEvent& event, std::string* result) {
void ApppendTouchPointDetails(const WebTouchPoint& point, std::string* result) {
StringAppendF(result,
" (ID: %d, State: %d, ScreenPos: (%f, %f), Pos: (%f, %f),"
- " Radius: (%f, %f), Rot: %f, Force: %f),\n",
+ " Radius: (%f, %f), Rot: %f, Force: %f,"
+ " Tilt: (%d, %d)),\n",
point.id,
point.state,
point.screenPosition.x,
@@ -103,7 +104,9 @@ void ApppendTouchPointDetails(const WebTouchPoint& point, std::string* result) {
point.radiusX,
point.radiusY,
point.rotationAngle,
- point.force);
+ point.force,
+ point.tiltX,
+ point.tiltY);
}
void ApppendEventDetails(const WebTouchEvent& event, std::string* result) {
diff --git a/content/content_tests.gypi b/content/content_tests.gypi
index cbfdb7b..04ba14e 100644
--- a/content/content_tests.gypi
+++ b/content/content_tests.gypi
@@ -528,6 +528,7 @@
'browser/renderer_host/input/mock_input_ack_handler.h',
'browser/renderer_host/input/mock_input_router_client.cc',
'browser/renderer_host/input/mock_input_router_client.h',
+ 'browser/renderer_host/input/motion_event_web_unittest.cc',
'browser/renderer_host/input/mouse_wheel_rails_filter_unittest_mac.cc',
'browser/renderer_host/input/render_widget_host_latency_tracker_unittest.cc',
'browser/renderer_host/input/stylus_text_selector_unittest.cc',
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
index a3e7fd3..dfbe5f2 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
@@ -1222,6 +1222,8 @@ public class ContentViewCore implements AccessibilityStateChangeListener, Screen
event.getTouchMajor(), pointerCount > 1 ? event.getTouchMajor(1) : 0,
event.getTouchMinor(), pointerCount > 1 ? event.getTouchMinor(1) : 0,
event.getOrientation(), pointerCount > 1 ? event.getOrientation(1) : 0,
+ event.getAxisValue(MotionEvent.AXIS_TILT),
+ pointerCount > 1 ? event.getAxisValue(MotionEvent.AXIS_TILT, 1) : 0,
event.getRawX(), event.getRawY(),
event.getToolType(0),
pointerCount > 1 ? event.getToolType(1) : MotionEvent.TOOL_TYPE_UNKNOWN,
@@ -3312,6 +3314,7 @@ public class ContentViewCore implements AccessibilityStateChangeListener, Screen
float touchMajor0, float touchMajor1,
float touchMinor0, float touchMinor1,
float orientation0, float orientation1,
+ float tilt0, float tilt1,
float rawX, float rawY,
int androidToolType0, int androidToolType1,
int androidButtonState, int androidMetaState,
diff --git a/ui/events/blink/blink_event_util.cc b/ui/events/blink/blink_event_util.cc
index 659adf3..5ceb267 100644
--- a/ui/events/blink/blink_event_util.cc
+++ b/ui/events/blink/blink_event_util.cc
@@ -125,7 +125,8 @@ WebTouchPoint CreateWebTouchPoint(const MotionEvent& event,
DCHECK_LE(minor_radius, major_radius);
DCHECK(!major_radius || minor_radius);
- float orientation_deg = event.GetOrientation(pointer_index) * 180.f / M_PI;
+ float orientation_rad = event.GetOrientation(pointer_index);
+ float orientation_deg = orientation_rad * 180.f / M_PI;
DCHECK_GE(major_radius, 0);
DCHECK_GE(minor_radius, 0);
DCHECK_GE(major_radius, minor_radius);
@@ -158,6 +159,18 @@ WebTouchPoint CreateWebTouchPoint(const MotionEvent& event,
touch.force = event.GetPressure(pointer_index);
+ if (event.GetToolType(pointer_index) == MotionEvent::TOOL_TYPE_STYLUS) {
+ // A stylus points to a direction specified by orientation and tilts to
+ // the opposite direction. Coordinate system is left-handed.
+ float tilt_rad = event.GetTilt(pointer_index);
+ float r = sin(tilt_rad);
+ float z = cos(tilt_rad);
+ touch.tiltX = lround(atan2(sin(-orientation_rad) * r, z) * 180.f / M_PI);
+ touch.tiltY = lround(atan2(cos(-orientation_rad) * r, z) * 180.f / M_PI);
+ } else {
+ touch.tiltX = touch.tiltY = 0;
+ }
+
return touch;
}
diff --git a/ui/events/gesture_detection/motion_event.h b/ui/events/gesture_detection/motion_event.h
index a20abf5..f06e0840 100644
--- a/ui/events/gesture_detection/motion_event.h
+++ b/ui/events/gesture_detection/motion_event.h
@@ -65,6 +65,7 @@ class GESTURE_DETECTION_EXPORT MotionEvent {
virtual float GetTouchMinor(size_t pointer_index) const = 0;
virtual float GetOrientation(size_t pointer_index) const = 0;
virtual float GetPressure(size_t pointer_index) const = 0;
+ virtual float GetTilt(size_t pointer_index) const = 0;
virtual ToolType GetToolType(size_t pointer_index) const = 0;
virtual int GetButtonState() const = 0;
virtual int GetFlags() const = 0;
@@ -103,6 +104,7 @@ class GESTURE_DETECTION_EXPORT MotionEvent {
float GetOrientation() const { return GetOrientation(0); }
float GetPressure() const { return GetPressure(0); }
+ float GetTilt() const { return GetTilt(0); }
ToolType GetToolType() const { return GetToolType(0); }
// O(N) search of pointers (use sparingly!). Returns -1 if |id| nonexistent.
diff --git a/ui/events/gesture_detection/motion_event_buffer_unittest.cc b/ui/events/gesture_detection/motion_event_buffer_unittest.cc
index 5e23bd5..21a9408 100644
--- a/ui/events/gesture_detection/motion_event_buffer_unittest.cc
+++ b/ui/events/gesture_detection/motion_event_buffer_unittest.cc
@@ -101,6 +101,7 @@ class MotionEventBufferTest : public testing::Test,
EXPECT_EQ(a.GetTouchMinor(i), b.GetTouchMinor(bi));
EXPECT_EQ(a.GetOrientation(i), b.GetOrientation(bi));
EXPECT_EQ(a.GetPressure(i), b.GetPressure(bi));
+ EXPECT_EQ(a.GetTilt(i), b.GetTilt(bi));
EXPECT_EQ(a.GetToolType(i), b.GetToolType(bi));
}
diff --git a/ui/events/gesture_detection/motion_event_generic.cc b/ui/events/gesture_detection/motion_event_generic.cc
index be367bd..56d3839 100644
--- a/ui/events/gesture_detection/motion_event_generic.cc
+++ b/ui/events/gesture_detection/motion_event_generic.cc
@@ -29,6 +29,7 @@ PointerProperties::PointerProperties(float x, float y, float touch_major)
touch_major(touch_major),
touch_minor(0),
orientation(0),
+ tilt(0),
source_device_id(0) {
}
@@ -44,6 +45,7 @@ PointerProperties::PointerProperties(const MotionEvent& event,
touch_major(event.GetTouchMajor(pointer_index)),
touch_minor(event.GetTouchMinor(pointer_index)),
orientation(event.GetOrientation(pointer_index)),
+ tilt(event.GetTilt(pointer_index)),
source_device_id(0) {
}
@@ -170,6 +172,11 @@ float MotionEventGeneric::GetPressure(size_t pointer_index) const {
return pointers_[pointer_index].pressure;
}
+float MotionEventGeneric::GetTilt(size_t pointer_index) const {
+ DCHECK_LT(pointer_index, pointers_->size());
+ return pointers_[pointer_index].tilt;
+}
+
MotionEvent::ToolType MotionEventGeneric::GetToolType(
size_t pointer_index) const {
DCHECK_LT(pointer_index, pointers_->size());
diff --git a/ui/events/gesture_detection/motion_event_generic.h b/ui/events/gesture_detection/motion_event_generic.h
index 2a9a606..71dc92b 100644
--- a/ui/events/gesture_detection/motion_event_generic.h
+++ b/ui/events/gesture_detection/motion_event_generic.h
@@ -34,6 +34,7 @@ struct GESTURE_DETECTION_EXPORT PointerProperties {
float touch_major;
float touch_minor;
float orientation;
+ float tilt;
// source_device_id is only used on Aura.
int source_device_id;
};
@@ -62,6 +63,7 @@ class GESTURE_DETECTION_EXPORT MotionEventGeneric : public MotionEvent {
float GetTouchMinor(size_t pointer_index) const override;
float GetOrientation(size_t pointer_index) const override;
float GetPressure(size_t pointer_index) const override;
+ float GetTilt(size_t pointer_index) const override;
ToolType GetToolType(size_t pointer_index) const override;
int GetButtonState() const override;
int GetFlags() const override;
diff --git a/ui/events/test/motion_event_test_utils.cc b/ui/events/test/motion_event_test_utils.cc
index 0a3f80d..ec05291 100644
--- a/ui/events/test/motion_event_test_utils.cc
+++ b/ui/events/test/motion_event_test_utils.cc
@@ -213,6 +213,7 @@ std::string ToString(const MotionEvent& event) {
<< event.GetTouchMinor(pi) << ")"
<< "\n Orientation: " << event.GetOrientation(pi)
<< "\n Pressure: " << event.GetPressure(pi)
+ << "\n Tilt: " << event.GetTilt(pi)
<< "\n Tool: " << event.GetToolType(pi);
if (history_size) {
ss << "\n History: [";