diff options
author | kouhei@chromium.org <kouhei@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-12 01:08:17 +0000 |
---|---|---|
committer | kouhei@chromium.org <kouhei@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-12 01:08:17 +0000 |
commit | 37a8c7115ccc04291be1283b0266fd0ec63ad0f0 (patch) | |
tree | 42b44c4f47d6dee70ae663a164a080d6f4eaf015 | |
parent | 82747807bdba2c2a7f7c7097a8ef2a225491a20b (diff) | |
download | chromium_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
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; + } + } + } +} |