summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkouhei@chromium.org <kouhei@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-12 01:08:17 +0000
committerkouhei@chromium.org <kouhei@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-12 01:08:17 +0000
commit37a8c7115ccc04291be1283b0266fd0ec63ad0f0 (patch)
tree42b44c4f47d6dee70ae663a164a080d6f4eaf015
parent82747807bdba2c2a7f7c7097a8ef2a225491a20b (diff)
downloadchromium_src-37a8c7115ccc04291be1283b0266fd0ec63ad0f0.zip
chromium_src-37a8c7115ccc04291be1283b0266fd0ec63ad0f0.tar.gz
chromium_src-37a8c7115ccc04291be1283b0266fd0ec63ad0f0.tar.bz2
SyntheticGestureTarget implementation for injecting synthetic input events.
This will be used from SyntheticGesture implementations such as SyntheticSmoothScrollGesture(New) to inject input events in a Android/aura specific way. The patch also includes fallback implementation in SyntheticGetsureTargetBase which passes the input events to RWH. BUG=297960 BUG=306459 Review URL: https://codereview.chromium.org/26664002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@234354 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--content/browser/android/browser_jni_registrar.cc3
-rw-r--r--content/browser/android/content_view_core_impl.cc9
-rw-r--r--content/browser/android/content_view_core_impl.h4
-rw-r--r--content/browser/renderer_host/input/synthetic_gesture_target_android.cc83
-rw-r--r--content/browser/renderer_host/input/synthetic_gesture_target_android.h56
-rw-r--r--content/browser/renderer_host/input/synthetic_gesture_target_aura.cc74
-rw-r--r--content/browser/renderer_host/input/synthetic_gesture_target_aura.h39
-rw-r--r--content/browser/renderer_host/input/synthetic_gesture_target_base.cc104
-rw-r--r--content/browser/renderer_host/input/synthetic_gesture_target_base.h67
-rw-r--r--content/browser/renderer_host/render_widget_host_view_android.cc7
-rw-r--r--content/browser/renderer_host/render_widget_host_view_android.h2
-rw-r--r--content/browser/renderer_host/render_widget_host_view_aura.cc7
-rw-r--r--content/browser/renderer_host/render_widget_host_view_aura.h2
-rw-r--r--content/browser/renderer_host/render_widget_host_view_base.cc9
-rw-r--r--content/browser/renderer_host/render_widget_host_view_base.h2
-rw-r--r--content/content_browser.gypi6
-rw-r--r--content/content_jni.gypi1
-rw-r--r--content/port/browser/render_widget_host_view_port.h6
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java6
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/TouchEventSynthesizer.java118
20 files changed, 605 insertions, 0 deletions
diff --git a/content/browser/android/browser_jni_registrar.cc b/content/browser/android/browser_jni_registrar.cc
index 72c7f17..2d5ac88 100644
--- a/content/browser/android/browser_jni_registrar.cc
+++ b/content/browser/android/browser_jni_registrar.cc
@@ -30,6 +30,7 @@
#include "content/browser/media/android/media_resource_getter_impl.h"
#include "content/browser/power_save_blocker_android.h"
#include "content/browser/renderer_host/ime_adapter_android.h"
+#include "content/browser/renderer_host/input/synthetic_gesture_target_android.h"
#include "content/browser/renderer_host/java/java_bound_object.h"
#include "content/browser/speech/speech_recognizer_impl_android.h"
@@ -64,6 +65,8 @@ base::android::RegistrationMethod kContentRegisteredMethods[] = {
{"RegisterImeAdapter", content::RegisterImeAdapter},
{"SpeechRecognizerImplAndroid",
content::SpeechRecognizerImplAndroid::RegisterSpeechRecognizer},
+ {"TouchEventSynthesizer",
+ content::SyntheticGestureTargetAndroid::RegisterTouchEventSynthesizer},
{"TouchPoint", content::RegisterTouchPoint},
{"TracingControllerAndroid", content::RegisterTracingControllerAndroid},
{"VibrationMessageFilter", content::VibrationMessageFilter::Register},
diff --git a/content/browser/android/content_view_core_impl.cc b/content/browser/android/content_view_core_impl.cc
index 1ad9f6e..5883f93 100644
--- a/content/browser/android/content_view_core_impl.cc
+++ b/content/browser/android/content_view_core_impl.cc
@@ -578,6 +578,15 @@ void ContentViewCoreImpl::ShowDisambiguationPopup(
java_bitmap.obj());
}
+ScopedJavaLocalRef<jobject> ContentViewCoreImpl::CreateTouchEventSynthesizer() {
+ JNIEnv* env = AttachCurrentThread();
+
+ ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
+ if (obj.is_null())
+ return ScopedJavaLocalRef<jobject>();
+ return Java_ContentViewCore_createTouchEventSynthesizer(env, obj.obj());
+}
+
ScopedJavaLocalRef<jobject> ContentViewCoreImpl::CreateOnePointTouchGesture(
int32 start_x, int32 start_y, int32 delta_x, int32 delta_y) {
JNIEnv* env = AttachCurrentThread();
diff --git a/content/browser/android/content_view_core_impl.h b/content/browser/android/content_view_core_impl.h
index d8a7e63..ce6cb59 100644
--- a/content/browser/android/content_view_core_impl.h
+++ b/content/browser/android/content_view_core_impl.h
@@ -278,6 +278,10 @@ class ContentViewCoreImpl : public ContentViewCore,
void ShowDisambiguationPopup(
const gfx::Rect& target_rect, const SkBitmap& zoomed_bitmap);
+ // Creates a java-side touch event, used for injecting touch event for
+ // testing/benchmarking purposes
+ base::android::ScopedJavaLocalRef<jobject> CreateTouchEventSynthesizer();
+
// Creates a java-side touch gesture, e.g. used by
// chrome.gpuBenchmarking.smoothScrollBy.
base::android::ScopedJavaLocalRef<jobject> CreateOnePointTouchGesture(
diff --git a/content/browser/renderer_host/input/synthetic_gesture_target_android.cc b/content/browser/renderer_host/input/synthetic_gesture_target_android.cc
new file mode 100644
index 0000000..d8d3836
--- /dev/null
+++ b/content/browser/renderer_host/input/synthetic_gesture_target_android.cc
@@ -0,0 +1,83 @@
+// Copyright 2013 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.
+
+#include "content/browser/renderer_host/input/synthetic_gesture_target_android.h"
+
+#include "content/browser/android/content_view_core_impl.h"
+#include "jni/TouchEventSynthesizer_jni.h"
+#include "third_party/WebKit/public/web/WebInputEvent.h"
+
+using blink::WebTouchEvent;
+
+namespace content {
+
+SyntheticGestureTargetAndroid::SyntheticGestureTargetAndroid(
+ RenderWidgetHostImpl* host,
+ base::android::ScopedJavaLocalRef<jobject> touch_event_synthesizer)
+ : SyntheticGestureTargetBase(host),
+ touch_event_synthesizer_(touch_event_synthesizer) {
+ DCHECK(!touch_event_synthesizer_.is_null());
+}
+
+SyntheticGestureTargetAndroid::~SyntheticGestureTargetAndroid() {
+}
+
+bool SyntheticGestureTargetAndroid::RegisterTouchEventSynthesizer(JNIEnv* env) {
+ return RegisterNativesImpl(env);
+}
+
+void SyntheticGestureTargetAndroid::TouchSetPointer(
+ JNIEnv* env, int index, int x, int y, int id) {
+ Java_TouchEventSynthesizer_setPointer(env, touch_event_synthesizer_.obj(),
+ index, x, y, id);
+}
+
+void SyntheticGestureTargetAndroid::TouchInject(
+ JNIEnv* env, Action action, int pointer_count) {
+ Java_TouchEventSynthesizer_inject(env, touch_event_synthesizer_.obj(),
+ static_cast<int>(action), pointer_count);
+}
+
+void SyntheticGestureTargetAndroid::QueueWebTouchEventToPlatform(
+ const blink::WebTouchEvent& web_touch, const ui::LatencyInfo&) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+
+ SyntheticGestureTargetAndroid::Action action =
+ SyntheticGestureTargetAndroid::ActionInvalid;
+ switch (web_touch.type) {
+ case blink::WebInputEvent::TouchStart:
+ action = SyntheticGestureTargetAndroid::ActionStart;
+ break;
+ case blink::WebInputEvent::TouchMove:
+ action = SyntheticGestureTargetAndroid::ActionMove;
+ break;
+ case blink::WebInputEvent::TouchCancel:
+ action = SyntheticGestureTargetAndroid::ActionCancel;
+ break;
+ case blink::WebInputEvent::TouchEnd:
+ action = SyntheticGestureTargetAndroid::ActionEnd;
+ break;
+ default:
+ NOTREACHED();
+ }
+ const unsigned num_touches = web_touch.touchesLength;
+ for (unsigned i = 0; i < num_touches; ++i) {
+ const blink::WebTouchPoint* point = &web_touch.touches[i];
+ TouchSetPointer(env, i, point->position.x, point->position.y, point->id);
+ }
+
+ TouchInject(env, action, num_touches);
+}
+
+SyntheticGestureParams::GestureSourceType
+SyntheticGestureTargetAndroid::GetDefaultSyntheticGestureSourceType() const {
+ return SyntheticGestureParams::TOUCH_INPUT;
+}
+
+bool SyntheticGestureTargetAndroid::SupportsSyntheticGestureSourceType(
+ SyntheticGestureParams::GestureSourceType gesture_source_type) const {
+ return gesture_source_type == SyntheticGestureParams::TOUCH_INPUT;
+}
+
+} // namespace content
diff --git a/content/browser/renderer_host/input/synthetic_gesture_target_android.h b/content/browser/renderer_host/input/synthetic_gesture_target_android.h
new file mode 100644
index 0000000..04a98e6
--- /dev/null
+++ b/content/browser/renderer_host/input/synthetic_gesture_target_android.h
@@ -0,0 +1,56 @@
+// Copyright 2013 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.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_GESTURE_TARGET_ANDROID_H_
+#define CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_GESTURE_TARGET_ANDROID_H_
+
+#include "base/android/jni_android.h"
+#include "base/time/time.h"
+#include "content/browser/renderer_host/input/synthetic_gesture_target_base.h"
+
+namespace content {
+
+class ContentViewCoreImpl;
+
+class SyntheticGestureTargetAndroid : public SyntheticGestureTargetBase {
+ public:
+ SyntheticGestureTargetAndroid(
+ RenderWidgetHostImpl* host,
+ base::android::ScopedJavaLocalRef<jobject> touch_event_synthesizer);
+ virtual ~SyntheticGestureTargetAndroid();
+
+ static bool RegisterTouchEventSynthesizer(JNIEnv* env);
+
+ virtual void QueueWebTouchEventToPlatform(
+ const blink::WebTouchEvent& web_touch,
+ const ui::LatencyInfo& latency_info) OVERRIDE;
+
+ // SyntheticGestureTarget:
+ virtual SyntheticGestureParams::GestureSourceType
+ GetDefaultSyntheticGestureSourceType() const OVERRIDE;
+ virtual bool SupportsSyntheticGestureSourceType(
+ SyntheticGestureParams::GestureSourceType gesture_source_type) const
+ OVERRIDE;
+
+ private:
+ // Enum values below need to be kept in sync with TouchEventSynthesizer.java
+ enum Action {
+ ActionInvalid = -1,
+ ActionStart = 0,
+ ActionMove = 1,
+ ActionCancel = 2,
+ ActionEnd = 3
+ };
+
+ void TouchSetPointer(JNIEnv* env, int index, int x, int y, int id);
+ void TouchInject(JNIEnv* env, Action action, int pointer_count);
+
+ base::android::ScopedJavaGlobalRef<jobject> touch_event_synthesizer_;
+
+ DISALLOW_COPY_AND_ASSIGN(SyntheticGestureTargetAndroid);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_GESTURE_TARGET_ANDROID_H_
diff --git a/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc b/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc
new file mode 100644
index 0000000..4db289a
--- /dev/null
+++ b/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc
@@ -0,0 +1,74 @@
+// Copyright 2013 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.
+
+#include "content/browser/renderer_host/input/synthetic_gesture_target_aura.h"
+
+#include "content/browser/renderer_host/render_widget_host_impl.h"
+#include "content/browser/renderer_host/render_widget_host_view_aura.h"
+#include "content/browser/renderer_host/ui_events_helper.h"
+#include "content/common/input/input_event.h"
+#include "ui/aura/client/screen_position_client.h"
+#include "ui/aura/root_window.h"
+#include "ui/aura/window.h"
+
+using blink::WebTouchEvent;
+using blink::WebMouseWheelEvent;
+
+namespace content {
+
+SyntheticGestureTargetAura::SyntheticGestureTargetAura(
+ RenderWidgetHostImpl* host)
+ : SyntheticGestureTargetBase(host) {
+}
+
+void SyntheticGestureTargetAura::QueueWebTouchEventToPlatform(
+ const WebTouchEvent& web_touch,
+ const ui::LatencyInfo& latency_info) {
+ aura::Window* window = render_widget_host()->GetView()->GetNativeView();
+ aura::RootWindow* root_window =
+ static_cast<aura::RootWindow*>(window->GetRootWindow());
+ aura::client::ScreenPositionClient* position_client =
+ aura::client::GetScreenPositionClient(root_window);
+ DCHECK(position_client);
+
+ TouchEventWithLatencyInfo touch_with_latency(web_touch, latency_info);
+
+ // SyntheticGesture may skip calculating screenPosition, so we will fill it
+ // in here. "screenPosition" is converted from "position".
+ const size_t num_touches = touch_with_latency.event.touchesLength;
+ for (size_t i = 0; i < num_touches; ++ i) {
+ blink::WebTouchPoint* point = &touch_with_latency.event.touches[i];
+ gfx::Point position(point->position.x, point->position.y);
+ position_client->ConvertPointToScreen(window, &position);
+ point->screenPosition.x = position.x();
+ point->screenPosition.y = position.y();
+ }
+
+ ScopedVector<ui::TouchEvent> events;
+ bool conversion_success = MakeUITouchEventsFromWebTouchEvents(
+ touch_with_latency, &events, SCREEN_COORDINATES);
+ DCHECK(conversion_success);
+
+ aura::RootWindowHostDelegate* root_window_host_delegate =
+ root_window->AsRootWindowHostDelegate();
+ for (ScopedVector<ui::TouchEvent>::iterator iter = events.begin(),
+ end = events.end(); iter != end; ++iter) {
+ root_window_host_delegate->OnHostTouchEvent(*iter);
+ }
+}
+
+SyntheticGestureParams::GestureSourceType
+SyntheticGestureTargetAura::GetDefaultSyntheticGestureSourceType() const {
+ // TODO(297960): Change this to MOUSE_INPUT when a native impl of
+ // QueueWebMouseWheelEventToPlatform is ready.
+ return SyntheticGestureParams::TOUCH_INPUT;
+}
+
+bool SyntheticGestureTargetAura::SupportsSyntheticGestureSourceType(
+ SyntheticGestureParams::GestureSourceType gesture_source_type) const {
+ return gesture_source_type == SyntheticGestureParams::TOUCH_INPUT ||
+ gesture_source_type == SyntheticGestureParams::MOUSE_INPUT;
+}
+
+} // namespace content
diff --git a/content/browser/renderer_host/input/synthetic_gesture_target_aura.h b/content/browser/renderer_host/input/synthetic_gesture_target_aura.h
new file mode 100644
index 0000000..3903644
--- /dev/null
+++ b/content/browser/renderer_host/input/synthetic_gesture_target_aura.h
@@ -0,0 +1,39 @@
+// Copyright 2013 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.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_GESTURE_TARGET_AURA_H_
+#define CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_GESTURE_TARGET_AURA_H_
+
+#include "base/time/time.h"
+#include "content/browser/renderer_host/input/synthetic_gesture_target_base.h"
+#include "content/common/input/synthetic_gesture_params.h"
+
+namespace content {
+
+class InputEvent;
+
+// SyntheticGestureTarget implementation for aura
+class SyntheticGestureTargetAura : public SyntheticGestureTargetBase {
+ public:
+ explicit SyntheticGestureTargetAura(RenderWidgetHostImpl* host);
+
+ // SyntheticGestureTargetBase:
+ virtual void QueueWebTouchEventToPlatform(
+ const blink::WebTouchEvent& web_touch,
+ const ui::LatencyInfo& latency_info) OVERRIDE;
+
+ // SyntheticGestureTarget:
+ virtual SyntheticGestureParams::GestureSourceType
+ GetDefaultSyntheticGestureSourceType() const OVERRIDE;
+ virtual bool SupportsSyntheticGestureSourceType(
+ SyntheticGestureParams::GestureSourceType gesture_source_type) const
+ OVERRIDE;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SyntheticGestureTargetAura);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_GESTURE_TARGET_AURA_H_
diff --git a/content/browser/renderer_host/input/synthetic_gesture_target_base.cc b/content/browser/renderer_host/input/synthetic_gesture_target_base.cc
new file mode 100644
index 0000000..3fc93c1
--- /dev/null
+++ b/content/browser/renderer_host/input/synthetic_gesture_target_base.cc
@@ -0,0 +1,104 @@
+// Copyright 2013 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.
+
+#include "content/browser/renderer_host/input/synthetic_gesture_target_base.h"
+
+#include "content/browser/renderer_host/render_widget_host_impl.h"
+#include "content/browser/renderer_host/ui_events_helper.h"
+#include "content/common/input/input_event.h"
+#include "ui/events/event.h"
+#include "ui/events/latency_info.h"
+
+using blink::WebInputEvent;
+using blink::WebTouchEvent;
+using blink::WebMouseEvent;
+using blink::WebMouseWheelEvent;
+
+namespace content {
+
+namespace {
+
+// How many milliseconds apart synthetic scroll messages should be sent.
+const int kSyntheticGestureMessageIntervalMs = 16;
+
+} // namespace
+
+SyntheticGestureTargetBase::SyntheticGestureTargetBase(
+ RenderWidgetHostImpl* host)
+ : host_(host) {
+}
+
+SyntheticGestureTargetBase::~SyntheticGestureTargetBase() {
+}
+
+void SyntheticGestureTargetBase::QueueInputEventToPlatform(
+ const InputEvent& event) {
+ const WebInputEvent* web_event = event.web_event.get();
+ if (WebInputEvent::isTouchEventType(web_event->type)) {
+ DCHECK(SupportsSyntheticGestureSourceType(
+ SyntheticGestureParams::TOUCH_INPUT));
+
+ const WebTouchEvent* web_touch =
+ static_cast<const WebTouchEvent*>(web_event);
+ QueueWebTouchEventToPlatform(*web_touch, event.latency_info);
+ } else if (web_event->type == WebInputEvent::MouseWheel) {
+ DCHECK(SupportsSyntheticGestureSourceType(
+ SyntheticGestureParams::MOUSE_INPUT));
+
+ const WebMouseWheelEvent* web_wheel =
+ static_cast<const WebMouseWheelEvent*>(web_event);
+ QueueWebMouseWheelEventToPlatform(*web_wheel, event.latency_info);
+ } else if (WebInputEvent::isMouseEventType(web_event->type)) {
+ DCHECK(SupportsSyntheticGestureSourceType(
+ SyntheticGestureParams::MOUSE_INPUT));
+
+ const WebMouseEvent* web_mouse =
+ static_cast<const WebMouseEvent*>(web_event);
+ QueueWebMouseEventToPlatform(*web_mouse, event.latency_info);
+ } else {
+ NOTREACHED();
+ }
+}
+
+void SyntheticGestureTargetBase::QueueWebTouchEventToPlatform(
+ const blink::WebTouchEvent& web_touch,
+ const ui::LatencyInfo& latency_info) {
+ host_->ForwardTouchEventWithLatencyInfo(web_touch, latency_info);
+}
+
+void SyntheticGestureTargetBase::QueueWebMouseWheelEventToPlatform(
+ const blink::WebMouseWheelEvent& web_wheel,
+ const ui::LatencyInfo& latency_info) {
+ host_->ForwardWheelEventWithLatencyInfo(
+ MouseWheelEventWithLatencyInfo(web_wheel, latency_info));
+}
+
+void SyntheticGestureTargetBase::QueueWebMouseEventToPlatform(
+ const blink::WebMouseEvent& web_mouse,
+ const ui::LatencyInfo& latency_info) {
+ host_->ForwardMouseEventWithLatencyInfo(
+ MouseEventWithLatencyInfo(web_mouse, latency_info));
+}
+
+void SyntheticGestureTargetBase::OnSyntheticGestureCompleted(
+ SyntheticGestureNew::Result result) {
+}
+
+base::TimeDelta
+SyntheticGestureTargetBase::GetSyntheticGestureUpdateRate() const {
+ return base::TimeDelta::FromMilliseconds(kSyntheticGestureMessageIntervalMs);
+}
+
+SyntheticGestureParams::GestureSourceType
+SyntheticGestureTargetBase::GetDefaultSyntheticGestureSourceType() const {
+ return SyntheticGestureParams::MOUSE_INPUT;
+}
+
+bool SyntheticGestureTargetBase::SupportsSyntheticGestureSourceType(
+ SyntheticGestureParams::GestureSourceType gesture_source_type) const {
+ return gesture_source_type == SyntheticGestureParams::MOUSE_INPUT ||
+ gesture_source_type == SyntheticGestureParams::TOUCH_INPUT;
+}
+
+} // namespace content
diff --git a/content/browser/renderer_host/input/synthetic_gesture_target_base.h b/content/browser/renderer_host/input/synthetic_gesture_target_base.h
new file mode 100644
index 0000000..b7b7e17
--- /dev/null
+++ b/content/browser/renderer_host/input/synthetic_gesture_target_base.h
@@ -0,0 +1,67 @@
+// Copyright 2013 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.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_GESTURE_TARGET_BASE_H_
+#define CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_GESTURE_TARGET_BASE_H_
+
+#include "base/time/time.h"
+#include "content/browser/renderer_host/input/synthetic_gesture_target.h"
+
+namespace ui {
+struct LatencyInfo;
+}
+
+namespace blink {
+class WebTouchEvent;
+class WebMouseEvent;
+class WebMouseWheelEvent;
+}
+
+namespace content {
+
+class RenderWidgetHostImpl;
+
+class SyntheticGestureTargetBase : public SyntheticGestureTarget {
+ public:
+ explicit SyntheticGestureTargetBase(RenderWidgetHostImpl* host);
+ virtual ~SyntheticGestureTargetBase();
+
+ virtual void QueueWebTouchEventToPlatform(
+ const blink::WebTouchEvent& web_touch,
+ const ui::LatencyInfo& latency_info);
+
+ virtual void QueueWebMouseWheelEventToPlatform(
+ const blink::WebMouseWheelEvent& web_wheel,
+ const ui::LatencyInfo& latency_info);
+
+ virtual void QueueWebMouseEventToPlatform(
+ const blink::WebMouseEvent& web_mouse,
+ const ui::LatencyInfo& latency_info);
+
+ // SyntheticGestureTarget:
+ virtual void QueueInputEventToPlatform(const InputEvent& event) OVERRIDE;
+
+ virtual void OnSyntheticGestureCompleted(
+ SyntheticGestureNew::Result result) OVERRIDE;
+
+ virtual base::TimeDelta GetSyntheticGestureUpdateRate() const OVERRIDE;
+
+ virtual SyntheticGestureParams::GestureSourceType
+ GetDefaultSyntheticGestureSourceType() const OVERRIDE;
+ virtual bool SupportsSyntheticGestureSourceType(
+ SyntheticGestureParams::GestureSourceType gesture_source_type) const
+ OVERRIDE;
+
+ protected:
+ RenderWidgetHostImpl* render_widget_host() { return host_; }
+
+ private:
+ RenderWidgetHostImpl* host_;
+
+ DISALLOW_COPY_AND_ASSIGN(SyntheticGestureTargetBase);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_GESTURE_TARGET_BASE_H_
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
index 6933cd1..ce4fe3f 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -35,6 +35,7 @@
#include "content/browser/renderer_host/dip_util.h"
#include "content/browser/renderer_host/generic_touch_gesture_android.h"
#include "content/browser/renderer_host/image_transport_factory_android.h"
+#include "content/browser/renderer_host/input/synthetic_gesture_target_android.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/common/gpu/client/gl_helper.h"
#include "content/common/gpu/gpu_messages.h"
@@ -615,6 +616,12 @@ void RenderWidgetHostViewAndroid::ShowDisambiguationPopup(
content_view_core_->ShowDisambiguationPopup(target_rect, zoomed_bitmap);
}
+scoped_ptr<SyntheticGestureTarget>
+RenderWidgetHostViewAndroid::CreateSyntheticGestureTarget() {
+ return scoped_ptr<SyntheticGestureTarget>(new SyntheticGestureTargetAndroid(
+ host_, content_view_core_->CreateTouchEventSynthesizer()));
+}
+
SyntheticGesture* RenderWidgetHostViewAndroid::CreateSmoothScrollGesture(
bool scroll_down, int pixels_to_scroll, int mouse_event_x,
int mouse_event_y) {
diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h
index fb0892a..ff80774 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.h
+++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -171,6 +171,8 @@ class RenderWidgetHostViewAndroid
gfx::Vector2dF current_fling_velocity) OVERRIDE;
virtual void ShowDisambiguationPopup(const gfx::Rect& target_rect,
const SkBitmap& zoomed_bitmap) OVERRIDE;
+ virtual scoped_ptr<SyntheticGestureTarget> CreateSyntheticGestureTarget()
+ OVERRIDE;
virtual SyntheticGesture* CreateSmoothScrollGesture(
bool scroll_down, int pixels_to_scroll, int mouse_event_x,
int mouse_event_y) OVERRIDE;
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index f005a78..b08e23d 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -25,6 +25,7 @@
#include "content/browser/gpu/compositor_util.h"
#include "content/browser/renderer_host/backing_store_aura.h"
#include "content/browser/renderer_host/dip_util.h"
+#include "content/browser/renderer_host/input/synthetic_gesture_target_aura.h"
#include "content/browser/renderer_host/overscroll_controller.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
@@ -2009,6 +2010,12 @@ void RenderWidgetHostViewAura::ProcessAckedTouchEvent(
}
}
+scoped_ptr<SyntheticGestureTarget>
+RenderWidgetHostViewAura::CreateSyntheticGestureTarget() {
+ return scoped_ptr<SyntheticGestureTarget>(
+ new SyntheticGestureTargetAura(host_));
+}
+
SyntheticGesture* RenderWidgetHostViewAura::CreateSmoothScrollGesture(
bool scroll_down,
int pixels_to_scroll,
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h
index 42c4526..ec94e3f 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.h
+++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -232,6 +232,8 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
virtual void ProcessAckedTouchEvent(
const TouchEventWithLatencyInfo& touch,
InputEventAckState ack_result) OVERRIDE;
+ virtual scoped_ptr<SyntheticGestureTarget> CreateSyntheticGestureTarget()
+ OVERRIDE;
virtual SyntheticGesture* CreateSmoothScrollGesture(
bool scroll_down,
int pixels_to_scroll,
diff --git a/content/browser/renderer_host/render_widget_host_view_base.cc b/content/browser/renderer_host/render_widget_host_view_base.cc
index 5ca099c..d67ffa4 100644
--- a/content/browser/renderer_host/render_widget_host_view_base.cc
+++ b/content/browser/renderer_host/render_widget_host_view_base.cc
@@ -8,6 +8,7 @@
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/renderer_host/basic_mouse_wheel_smooth_scroll_gesture.h"
+#include "content/browser/renderer_host/input/synthetic_gesture_target_base.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/port/browser/render_widget_host_view_frame_subscriber.h"
@@ -528,6 +529,14 @@ void RenderWidgetHostViewBase::ProcessAckedTouchEvent(
const TouchEventWithLatencyInfo& touch, InputEventAckState ack_result) {
}
+scoped_ptr<SyntheticGestureTarget>
+RenderWidgetHostViewBase::CreateSyntheticGestureTarget() {
+ RenderWidgetHostImpl* host =
+ RenderWidgetHostImpl::From(GetRenderWidgetHost());
+ return scoped_ptr<SyntheticGestureTarget>(
+ new SyntheticGestureTargetBase(host));
+}
+
// Platform implementation should override this method to allow frame
// subscription. Frame subscriber is set to RenderProcessHost, which is
// platform independent. It should be set to the specific presenter on each
diff --git a/content/browser/renderer_host/render_widget_host_view_base.h b/content/browser/renderer_host/render_widget_host_view_base.h
index abe318f..0c7bddd 100644
--- a/content/browser/renderer_host/render_widget_host_view_base.h
+++ b/content/browser/renderer_host/render_widget_host_view_base.h
@@ -71,6 +71,8 @@ class CONTENT_EXPORT RenderWidgetHostViewBase
GetBrowserAccessibilityManager() const OVERRIDE;
virtual void ProcessAckedTouchEvent(const TouchEventWithLatencyInfo& touch,
InputEventAckState ack_result) OVERRIDE;
+ virtual scoped_ptr<SyntheticGestureTarget> CreateSyntheticGestureTarget()
+ OVERRIDE;
virtual SyntheticGesture* CreateSmoothScrollGesture(
bool scroll_down, int pixels_to_scroll, int mouse_event_x,
int mouse_event_y) OVERRIDE;
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index 1fc3c68..a6aff10 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -843,6 +843,12 @@
'browser/renderer_host/input/synthetic_gesture_new.cc',
'browser/renderer_host/input/synthetic_gesture_new.h',
'browser/renderer_host/input/synthetic_gesture_target.h',
+ 'browser/renderer_host/input/synthetic_gesture_target_android.cc',
+ 'browser/renderer_host/input/synthetic_gesture_target_android.h',
+ 'browser/renderer_host/input/synthetic_gesture_target_aura.cc',
+ 'browser/renderer_host/input/synthetic_gesture_target_aura.h',
+ 'browser/renderer_host/input/synthetic_gesture_target_base.cc',
+ 'browser/renderer_host/input/synthetic_gesture_target_base.h',
'browser/renderer_host/input/synthetic_smooth_scroll_gesture_new.cc',
'browser/renderer_host/input/synthetic_smooth_scroll_gesture_new.h',
'browser/renderer_host/input/synthetic_web_input_event_builders.cc',
diff --git a/content/content_jni.gypi b/content/content_jni.gypi
index e8b3e96..3d23483 100644
--- a/content/content_jni.gypi
+++ b/content/content_jni.gypi
@@ -31,6 +31,7 @@
'public/android/java/src/org/chromium/content/browser/PowerSaveBlocker.java',
'public/android/java/src/org/chromium/content/browser/GenericTouchGesture.java',
'public/android/java/src/org/chromium/content/browser/SpeechRecognition.java',
+ 'public/android/java/src/org/chromium/content/browser/TouchEventSynthesizer.java',
'public/android/java/src/org/chromium/content/browser/TouchPoint.java',
'public/android/java/src/org/chromium/content/browser/TracingControllerAndroid.java',
'public/android/java/src/org/chromium/content/browser/VibrationMessageFilter.java',
diff --git a/content/port/browser/render_widget_host_view_port.h b/content/port/browser/render_widget_host_view_port.h
index 13f3766..bd13f73 100644
--- a/content/port/browser/render_widget_host_view_port.h
+++ b/content/port/browser/render_widget_host_view_port.h
@@ -6,6 +6,7 @@
#define CONTENT_PORT_BROWSER_RENDER_WIDGET_HOST_VIEW_PORT_H_
#include "base/callback.h"
+#include "base/memory/scoped_ptr.h"
#include "base/process/kill.h"
#include "base/strings/string16.h"
#include "cc/output/compositor_frame.h"
@@ -42,6 +43,7 @@ namespace content {
class BackingStore;
class RenderWidgetHostViewFrameSubscriber;
class SyntheticGesture;
+class SyntheticGestureTarget;
struct WebPluginGeometry;
struct NativeWebKeyboardEvent;
@@ -300,6 +302,10 @@ class CONTENT_EXPORT RenderWidgetHostViewPort : public RenderWidgetHostView,
// Called by the host when the input flush has completed.
virtual void OnDidFlushInput() = 0;
+ // Create a platform specific SyntheticGestureTarget implementation that will
+ // be used to inject synthetic input events.
+ virtual scoped_ptr<SyntheticGestureTarget> CreateSyntheticGestureTarget() = 0;
+
virtual void GestureEventAck(int gesture_event_type,
InputEventAckState ack_result) = 0;
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 be020c3..40090a4 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
@@ -2557,6 +2557,12 @@ public class ContentViewCore
@SuppressWarnings("unused")
@CalledByNative
+ private TouchEventSynthesizer createTouchEventSynthesizer() {
+ return new TouchEventSynthesizer(this);
+ }
+
+ @SuppressWarnings("unused")
+ @CalledByNative
private void onSelectionChanged(String text) {
mLastSelectedText = text;
}
diff --git a/content/public/android/java/src/org/chromium/content/browser/TouchEventSynthesizer.java b/content/public/android/java/src/org/chromium/content/browser/TouchEventSynthesizer.java
new file mode 100644
index 0000000..9c67587
--- /dev/null
+++ b/content/public/android/java/src/org/chromium/content/browser/TouchEventSynthesizer.java
@@ -0,0 +1,118 @@
+// Copyright 2013 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.
+
+package org.chromium.content.browser;
+
+import android.os.SystemClock;
+import android.view.MotionEvent;
+import android.view.MotionEvent.PointerProperties;
+import android.view.MotionEvent.PointerCoords;
+
+import org.chromium.base.CalledByNative;
+import org.chromium.base.JNINamespace;
+
+/**
+ * Provides a Java-side implementation for injecting synthetic touch events.
+ */
+@JNINamespace("content")
+public class TouchEventSynthesizer {
+ private static final int MAX_NUM_POINTERS = 16;
+
+ private static final int ACTION_START = 0;
+ private static final int ACTION_MOVE = 1;
+ private static final int ACTION_CANCEL = 2;
+ private static final int ACTION_END = 3;
+
+ private final ContentViewCore mContentViewCore;
+ private final PointerProperties[] mPointerProperties;
+ private final PointerCoords[] mPointerCoords;
+ private long mDownTime;
+
+ TouchEventSynthesizer(ContentViewCore contentViewCore) {
+ mContentViewCore = contentViewCore;
+ mPointerProperties = new PointerProperties[MAX_NUM_POINTERS];
+ mPointerCoords = new PointerCoords[MAX_NUM_POINTERS];
+ }
+
+ @CalledByNative
+ void setPointer(int index, int x, int y, int id) {
+ assert (0 <= index && index < MAX_NUM_POINTERS);
+
+ // Convert coordinates from density independent pixels to density dependent pixels.
+ float scaleFactor = mContentViewCore.getRenderCoordinates().getDeviceScaleFactor();
+
+ PointerCoords coords = new PointerCoords();
+ coords.x = scaleFactor * x;
+ coords.y = scaleFactor * y;
+ coords.pressure = 1.0f;
+ mPointerCoords[index] = coords;
+
+ PointerProperties properties = new PointerProperties();
+ properties.id = id;
+ mPointerProperties[index] = properties;
+ }
+
+ @CalledByNative
+ void inject(int action, int pointerCount) {
+ long time = SystemClock.uptimeMillis();
+
+ switch (action) {
+ case ACTION_START: {
+ mDownTime = time;
+ MotionEvent event = MotionEvent.obtain(
+ mDownTime, time, MotionEvent.ACTION_DOWN, 1,
+ mPointerProperties, mPointerCoords,
+ 0, 0, 1, 1, 0, 0, 0, 0);
+ mContentViewCore.onTouchEvent(event);
+ event.recycle();
+
+ if (pointerCount > 1) {
+ event = MotionEvent.obtain(
+ mDownTime, time, MotionEvent.ACTION_POINTER_DOWN,
+ pointerCount, mPointerProperties, mPointerCoords,
+ 0, 0, 1, 1, 0, 0, 0, 0);
+ mContentViewCore.onTouchEvent(event);
+ event.recycle();
+ }
+ break;
+ }
+ case ACTION_MOVE: {
+ MotionEvent event = MotionEvent.obtain(mDownTime, time,
+ MotionEvent.ACTION_MOVE,
+ pointerCount, mPointerProperties, mPointerCoords,
+ 0, 0, 1, 1, 0, 0, 0, 0);
+ mContentViewCore.onTouchEvent(event);
+ event.recycle();
+ break;
+ }
+ case ACTION_CANCEL: {
+ MotionEvent event = MotionEvent.obtain(
+ mDownTime, time, MotionEvent.ACTION_CANCEL, 1,
+ mPointerProperties, mPointerCoords,
+ 0, 0, 1, 1, 0, 0, 0, 0);
+ mContentViewCore.onTouchEvent(event);
+ event.recycle();
+ break;
+ }
+ case ACTION_END: {
+ if (pointerCount > 1) {
+ MotionEvent event = MotionEvent.obtain(
+ mDownTime, time, MotionEvent.ACTION_POINTER_UP,
+ pointerCount, mPointerProperties, mPointerCoords,
+ 0, 0, 1, 1, 0, 0, 0, 0);
+ mContentViewCore.onTouchEvent(event);
+ event.recycle();
+ }
+
+ MotionEvent event = MotionEvent.obtain(
+ mDownTime, time, MotionEvent.ACTION_UP, 1,
+ mPointerProperties, mPointerCoords,
+ 0, 0, 1, 1, 0, 0, 0, 0);
+ mContentViewCore.onTouchEvent(event);
+ event.recycle();
+ break;
+ }
+ }
+ }
+}