Index: content/browser/renderer_host/render_widget_host_view_android.cc |
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 ed4600ae92866fb66e7ba2a3c7d65ad8a64d5046..9d5d1597dc642cf351cdae0c28f153296cb889c0 100644 |
--- a/content/browser/renderer_host/render_widget_host_view_android.cc |
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc |
@@ -27,6 +27,7 @@ |
#include "cc/resources/single_release_callback.h" |
#include "cc/trees/layer_tree_host.h" |
#include "content/browser/accessibility/browser_accessibility_manager_android.h" |
+#include "content/browser/android/composited_touch_handle_drawable.h" |
#include "content/browser/android/content_view_core_impl.h" |
#include "content/browser/android/in_process/synchronous_compositor_impl.h" |
#include "content/browser/android/overscroll_glow.h" |
@@ -40,6 +41,7 @@ |
#include "content/browser/renderer_host/dip_util.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/input/touch_selection_controller.h" |
#include "content/browser/renderer_host/input/web_input_event_builders_android.h" |
#include "content/browser/renderer_host/input/web_input_event_util.h" |
#include "content/browser/renderer_host/render_process_host_impl.h" |
@@ -152,6 +154,20 @@ ui::GestureProvider::Config CreateGestureProviderConfig() { |
return config; |
} |
+TouchHandleOrientation SelectionBoundTypeToTouchHandleOrientation( |
+ cc::SelectionBoundType bound_type) { |
+ switch (bound_type) { |
+ case cc::SELECTION_BOUND_LEFT: |
+ return TOUCH_HANDLE_LEFT; |
+ case cc::SELECTION_BOUND_RIGHT: |
+ return TOUCH_HANDLE_RIGHT; |
+ case cc::SELECTION_BOUND_CENTER: |
+ return TOUCH_HANDLE_CENTER; |
+ case cc::SELECTION_BOUND_EMPTY: |
+ return TOUCH_HANDLE_ORIENTATION_UNDEFINED; |
+ } |
+} |
+ |
bool HasFixedPageScale(const cc::CompositorFrameMetadata& frame_metadata) { |
return frame_metadata.min_page_scale_factor == |
frame_metadata.max_page_scale_factor; |
@@ -557,6 +573,10 @@ bool RenderWidgetHostViewAndroid::OnTouchEvent( |
if (!host_) |
return false; |
+ if (selection_controller_ && |
+ selection_controller_->WillHandleTouchEvent(event)) |
+ return true; |
+ |
if (!gesture_provider_.OnTouchEvent(event)) |
return false; |
@@ -576,6 +596,12 @@ bool RenderWidgetHostViewAndroid::OnTouchEvent( |
return true; |
} |
+bool RenderWidgetHostViewAndroid::OnTouchHandleEvent( |
+ const ui::MotionEvent& event) { |
+ return selection_controller_ && |
+ selection_controller_->WillHandleTouchEvent(event); |
+} |
+ |
void RenderWidgetHostViewAndroid::ResetGestureDetection() { |
const ui::MotionEvent* current_down_event = |
gesture_provider_.GetCurrentDownEvent(); |
@@ -602,6 +628,8 @@ void RenderWidgetHostViewAndroid::ImeCancelComposition() { |
void RenderWidgetHostViewAndroid::FocusedNodeChanged(bool is_editable_node) { |
ime_adapter_android_.FocusedNodeChanged(is_editable_node); |
+ if (selection_controller_) |
+ selection_controller_->OnSelectionEditable(is_editable_node); |
} |
void RenderWidgetHostViewAndroid::RenderProcessGone( |
@@ -951,6 +979,38 @@ void RenderWidgetHostViewAndroid::SetOverlayVideoMode(bool enabled) { |
layer_->SetContentsOpaque(!enabled); |
} |
+void RenderWidgetHostViewAndroid::SetNeedsAnimate() { |
+ DCHECK(content_view_core_); |
+ content_view_core_->GetWindowAndroid()->SetNeedsAnimate(); |
+} |
+ |
+void RenderWidgetHostViewAndroid::MoveCaret(const gfx::PointF& position) { |
+ MoveCaret(gfx::Point(position.x(), position.y())); |
+} |
+ |
+void RenderWidgetHostViewAndroid::SelectBetweenCoordinates( |
+ const gfx::PointF& start, |
+ const gfx::PointF& end) { |
+ DCHECK(content_view_core_); |
+ content_view_core_->SelectBetweenCoordinates(start, end); |
+} |
+ |
+void RenderWidgetHostViewAndroid::OnSelectionEvent( |
+ SelectionEventType event, |
+ const gfx::PointF& position) { |
+ DCHECK(content_view_core_); |
+ content_view_core_->OnSelectionEvent(event, position); |
+} |
+ |
+scoped_ptr<TouchHandleDrawable> RenderWidgetHostViewAndroid::CreateDrawable() { |
+ DCHECK(content_view_core_); |
+ if (using_synchronous_compositor_) |
+ return content_view_core_->CreatePopupTouchHandleDrawable(); |
+ |
+ return scoped_ptr<TouchHandleDrawable>(new CompositedTouchHandleDrawable( |
+ content_view_core_->GetLayer(), GetDpiScale())); |
+} |
+ |
void RenderWidgetHostViewAndroid::SynchronousCopyContents( |
const gfx::Rect& src_subrect_in_pixel, |
const gfx::Size& dst_size_in_pixel, |
@@ -1019,28 +1079,17 @@ void RenderWidgetHostViewAndroid::UpdateSelectionBounds( |
if (!content_view_core_) |
return; |
- const cc::ViewportSelectionBound& anchor = frame_metadata.selection_anchor; |
- const cc::ViewportSelectionBound& focus = frame_metadata.selection_focus; |
- |
- if (cached_selection_anchor_ == anchor && cached_selection_focus_ == focus) |
- return; |
- |
- TRACE_EVENT0("input", "RenderWidgetHostViewAndroid::UpdateSelectionBounds"); |
- |
- cached_selection_anchor_ = anchor; |
- cached_selection_focus_ = focus; |
+ const cc::ViewportSelectionBound& start = frame_metadata.selection_start; |
+ const cc::ViewportSelectionBound& end = frame_metadata.selection_end; |
- content_view_core_->OnSelectionBoundsChanged( |
- anchor.viewport_rect.bottom_left(), |
- focus.viewport_rect.bottom_left(), |
- anchor.type == cc::SELECTION_BOUND_RIGHT |
- ? blink::WebTextDirectionRightToLeft |
- : blink::WebTextDirectionDefault, |
- focus.type == cc::SELECTION_BOUND_LEFT |
- ? blink::WebTextDirectionRightToLeft |
- : blink::WebTextDirectionDefault, |
- anchor.visible, |
- focus.visible); |
+ DCHECK(selection_controller_); |
+ selection_controller_->OnSelectionBoundsChanged( |
+ start.viewport_rect, |
+ SelectionBoundTypeToTouchHandleOrientation(start.type), |
+ start.visible, |
+ end.viewport_rect, |
+ SelectionBoundTypeToTouchHandleOrientation(end.type), |
+ end.visible); |
} |
void RenderWidgetHostViewAndroid::AcceleratedSurfaceInitialized(int host_id, |
@@ -1069,6 +1118,7 @@ void RenderWidgetHostViewAndroid::AttachLayers() { |
void RenderWidgetHostViewAndroid::RemoveLayers() { |
if (!content_view_core_) |
return; |
+ |
if (!layer_.get()) |
return; |
@@ -1076,12 +1126,16 @@ void RenderWidgetHostViewAndroid::RemoveLayers() { |
overscroll_effect_->Disable(); |
} |
-void RenderWidgetHostViewAndroid::SetNeedsAnimate() { |
- content_view_core_->GetWindowAndroid()->SetNeedsAnimate(); |
+bool RenderWidgetHostViewAndroid::Animate(base::TimeTicks frame_time) { |
+ bool needs_animate = overscroll_effect_->Animate(frame_time); |
+ if (selection_controller_) |
+ needs_animate |= selection_controller_->Animate(frame_time); |
+ return needs_animate; |
} |
-bool RenderWidgetHostViewAndroid::Animate(base::TimeTicks frame_time) { |
- return overscroll_effect_->Animate(frame_time); |
+float RenderWidgetHostViewAndroid::GetDpiScale() const { |
+ DCHECK(content_view_core_); |
+ return content_view_core_->GetDpiScale(); |
} |
void RenderWidgetHostViewAndroid::AcceleratedSurfacePostSubBuffer( |
@@ -1146,6 +1200,21 @@ void RenderWidgetHostViewAndroid::GestureEventAck( |
InputEventAckState RenderWidgetHostViewAndroid::FilterInputEvent( |
const blink::WebInputEvent& input_event) { |
+ if (selection_controller_) { |
+ switch (input_event.type) { |
+ case blink::WebInputEvent::GestureLongPress: |
+ case blink::WebInputEvent::GestureLongTap: |
+ selection_controller_->AllowAutomaticInsertionShowing(); |
+ selection_controller_->AllowAutomaticSelectionShowing(); |
+ break; |
+ case blink::WebInputEvent::GestureTap: |
+ selection_controller_->AllowAutomaticInsertionShowing(); |
+ break; |
+ default: |
+ break; |
+ } |
+ } |
+ |
if (content_view_core_ && |
content_view_core_->FilterInputEvent(input_event)) |
return INPUT_EVENT_ACK_STATE_CONSUMED; |
@@ -1253,6 +1322,11 @@ void RenderWidgetHostViewAndroid::MoveCaret(const gfx::Point& point) { |
host_->MoveCaret(point); |
} |
+void RenderWidgetHostViewAndroid::HideTextHandles() { |
+ if (selection_controller_) |
+ selection_controller_->HideAndDisallowAutomaticShowing(); |
+} |
+ |
SkColor RenderWidgetHostViewAndroid::GetCachedBackgroundColor() const { |
return cached_background_color_; |
} |
@@ -1262,7 +1336,7 @@ void RenderWidgetHostViewAndroid::DidOverscroll( |
if (!content_view_core_ || !layer_ || !is_showing_) |
return; |
- const float device_scale_factor = content_view_core_->GetDpiScale(); |
+ const float device_scale_factor = GetDpiScale(); |
if (overscroll_effect_->OnOverscrolled( |
content_view_core_->GetLayer(), |
base::TimeTicks::Now(), |
@@ -1291,6 +1365,7 @@ void RenderWidgetHostViewAndroid::SetContentViewCore( |
bool resize = false; |
if (content_view_core != content_view_core_) { |
+ selection_controller_.reset(); |
ReleaseLocksOnSurface(); |
resize = true; |
} |
@@ -1306,15 +1381,22 @@ void RenderWidgetHostViewAndroid::SetContentViewCore( |
} |
AttachLayers(); |
- if (content_view_core_ && !using_synchronous_compositor_) { |
+ |
+ if (!content_view_core_) |
+ return; |
+ |
+ if (!using_synchronous_compositor_) { |
content_view_core_->GetWindowAndroid()->AddObserver(this); |
observing_root_window_ = true; |
if (needs_begin_frame_) |
content_view_core_->GetWindowAndroid()->RequestVSyncUpdate(); |
} |
- if (resize && content_view_core_) |
+ if (resize) |
WasResized(); |
+ |
+ if (!selection_controller_) |
+ selection_controller_.reset(new TouchSelectionController(this)); |
} |
void RenderWidgetHostViewAndroid::RunAckCallbacks() { |
@@ -1477,8 +1559,8 @@ SkBitmap::Config RenderWidgetHostViewAndroid::PreferredReadbackFormat() { |
} |
void RenderWidgetHostViewAndroid::ShowSelectionHandlesAutomatically() { |
- if (content_view_core_) |
- content_view_core_->ShowSelectionHandlesAutomatically(); |
+ if (selection_controller_) |
+ selection_controller_->AllowAutomaticSelectionShowing(); |
} |
void RenderWidgetHostViewAndroid::SelectRange( |