| 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 a56a1f1660e45fe09e3874134584212b5fcc74be..129528b1298c2abe62c8456f82c2d9cb7d87792c 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"
|
| @@ -191,6 +193,8 @@ RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid(
|
| overscroll_effect_(OverscrollGlow::Create(overscroll_effect_enabled_)),
|
| gesture_provider_(CreateGestureProviderConfig(), this),
|
| gesture_text_selector_(this),
|
| + touch_scrolling_(false),
|
| + potentially_active_fling_count_(0),
|
| flush_input_requested_(false),
|
| accelerated_surface_route_id_(0),
|
| using_synchronous_compositor_(SynchronousCompositorImpl::FromID(
|
| @@ -560,6 +564,10 @@ bool RenderWidgetHostViewAndroid::OnTouchEvent(
|
| if (!host_)
|
| return false;
|
|
|
| + if (selection_controller_ &&
|
| + selection_controller_->WillHandleTouchEvent(event))
|
| + return true;
|
| +
|
| if (!gesture_provider_.OnTouchEvent(event))
|
| return false;
|
|
|
| @@ -579,6 +587,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();
|
| @@ -588,6 +602,10 @@ void RenderWidgetHostViewAndroid::ResetGestureDetection() {
|
| scoped_ptr<ui::MotionEvent> cancel_event = current_down_event->Cancel();
|
| DCHECK(cancel_event);
|
| OnTouchEvent(*cancel_event);
|
| +
|
| + touch_scrolling_ = false;
|
| + potentially_active_fling_count_ = 0;
|
| + OnContentScrollingChange();
|
| }
|
|
|
| void RenderWidgetHostViewAndroid::SetDoubleTapSupportEnabled(bool enabled) {
|
| @@ -605,6 +623,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(
|
| @@ -650,9 +670,34 @@ void RenderWidgetHostViewAndroid::SelectionChanged(const base::string16& text,
|
|
|
| void RenderWidgetHostViewAndroid::SelectionBoundsChanged(
|
| const ViewHostMsg_SelectionBounds_Params& params) {
|
| - if (content_view_core_) {
|
| - content_view_core_->OnSelectionBoundsChanged(params);
|
| + if (!selection_controller_)
|
| + return;
|
| +
|
| + gfx::RectF anchor_rect(params.anchor_rect);
|
| + gfx::RectF focus_rect(params.focus_rect);
|
| + if (params.is_anchor_first)
|
| + std::swap(anchor_rect, focus_rect);
|
| +
|
| + TouchHandleOrientation anchor_orientation(TOUCH_HANDLE_ORIENTATION_UNDEFINED);
|
| + TouchHandleOrientation focus_orientation(TOUCH_HANDLE_ORIENTATION_UNDEFINED);
|
| + if (params.anchor_rect == params.focus_rect) {
|
| + if (params.anchor_rect.x() && params.anchor_rect.y())
|
| + anchor_orientation = focus_orientation = TOUCH_HANDLE_CENTER;
|
| + } else {
|
| + anchor_orientation = params.anchor_dir == blink::WebTextDirectionRightToLeft
|
| + ? TOUCH_HANDLE_LEFT
|
| + : TOUCH_HANDLE_RIGHT;
|
| + focus_orientation = params.focus_dir == blink::WebTextDirectionRightToLeft
|
| + ? TOUCH_HANDLE_RIGHT
|
| + : TOUCH_HANDLE_LEFT;
|
| }
|
| +
|
| + selection_controller_->OnSelectionBoundsChanged(anchor_rect,
|
| + anchor_orientation,
|
| + true,
|
| + focus_rect,
|
| + focus_orientation,
|
| + true);
|
| }
|
|
|
| void RenderWidgetHostViewAndroid::ScrollOffsetChanged() {
|
| @@ -898,6 +943,8 @@ void RenderWidgetHostViewAndroid::InternalSwapCompositorFrame(
|
| SwapDelegatedFrame(output_surface_id, frame->delegated_frame_data.Pass());
|
| frame_evictor_->SwappedFrame(!host_->is_hidden());
|
|
|
| + // As the metadata update may trigger view invalidation, always call it after
|
| + // any potential compositor scheduling.
|
| OnFrameMetadataUpdated(frame->metadata);
|
| }
|
|
|
| @@ -954,6 +1001,47 @@ void RenderWidgetHostViewAndroid::SetOverlayVideoMode(bool enabled) {
|
| layer_->SetContentsOpaque(!enabled);
|
| }
|
|
|
| +bool RenderWidgetHostViewAndroid::SupportsAnimation() const {
|
| + // The synchronous (WebView) compositor does not have a proper browser
|
| + // compositor with which to drive animations.
|
| + return !using_synchronous_compositor_;
|
| +}
|
| +
|
| +void RenderWidgetHostViewAndroid::SetNeedsAnimate() {
|
| + DCHECK(content_view_core_);
|
| + DCHECK(!using_synchronous_compositor_);
|
| + 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(),
|
| + content_view_core_->GetDpiScale(),
|
| + content_view_core_->GetContext().obj()));
|
| +}
|
| +
|
| void RenderWidgetHostViewAndroid::SynchronousCopyContents(
|
| const gfx::Rect& src_subrect_in_pixel,
|
| const gfx::Size& dst_size_in_pixel,
|
| @@ -994,6 +1082,7 @@ void RenderWidgetHostViewAndroid::OnFrameMetadataUpdated(
|
|
|
| if (!content_view_core_)
|
| return;
|
| +
|
| // All offsets and sizes are in CSS pixels.
|
| content_view_core_->UpdateFrameInfo(
|
| frame_metadata.root_scroll_offset,
|
| @@ -1040,6 +1129,7 @@ void RenderWidgetHostViewAndroid::AttachLayers() {
|
| void RenderWidgetHostViewAndroid::RemoveLayers() {
|
| if (!content_view_core_)
|
| return;
|
| +
|
| if (!layer_.get())
|
| return;
|
|
|
| @@ -1047,12 +1137,20 @@ 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);
|
| +void RenderWidgetHostViewAndroid::OnContentScrollingChange() {
|
| + if (selection_controller_)
|
| + selection_controller_->SetTemporarilyHidden(IsContentScrolling());
|
| +}
|
| +
|
| +bool RenderWidgetHostViewAndroid::IsContentScrolling() const {
|
| + return touch_scrolling_ || potentially_active_fling_count_ > 0;
|
| }
|
|
|
| void RenderWidgetHostViewAndroid::AcceleratedSurfacePostSubBuffer(
|
| @@ -1111,12 +1209,47 @@ void RenderWidgetHostViewAndroid::ProcessAckedTouchEvent(
|
| void RenderWidgetHostViewAndroid::GestureEventAck(
|
| const blink::WebGestureEvent& event,
|
| InputEventAckState ack_result) {
|
| + switch (event.type) {
|
| + case blink::WebInputEvent::GestureScrollBegin:
|
| + touch_scrolling_ = true;
|
| + potentially_active_fling_count_ = 0;
|
| + OnContentScrollingChange();
|
| + break;
|
| + case blink::WebInputEvent::GestureScrollEnd:
|
| + touch_scrolling_ = false;
|
| + OnContentScrollingChange();
|
| + break;
|
| + case blink::WebInputEvent::GestureFlingStart:
|
| + touch_scrolling_ = false;
|
| + if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED)
|
| + ++potentially_active_fling_count_;
|
| + OnContentScrollingChange();
|
| + break;
|
| + default:
|
| + break;
|
| + }
|
| +
|
| if (content_view_core_)
|
| content_view_core_->OnGestureEventAck(event, ack_result);
|
| }
|
|
|
| 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_->ShowInsertionHandleAutomatically();
|
| + selection_controller_->ShowSelectionHandlesAutomatically();
|
| + break;
|
| + case blink::WebInputEvent::GestureTap:
|
| + selection_controller_->ShowInsertionHandleAutomatically();
|
| + break;
|
| + default:
|
| + break;
|
| + }
|
| + }
|
| +
|
| if (content_view_core_ &&
|
| content_view_core_->FilterInputEvent(input_event))
|
| return INPUT_EVENT_ACK_STATE_CONSUMED;
|
| @@ -1220,6 +1353,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_;
|
| }
|
| @@ -1244,6 +1382,11 @@ void RenderWidgetHostViewAndroid::DidOverscroll(
|
| }
|
|
|
| void RenderWidgetHostViewAndroid::DidStopFlinging() {
|
| + if (potentially_active_fling_count_) {
|
| + --potentially_active_fling_count_;
|
| + OnContentScrollingChange();
|
| + }
|
| +
|
| if (content_view_core_)
|
| content_view_core_->DidStopFlinging();
|
| }
|
| @@ -1258,6 +1401,7 @@ void RenderWidgetHostViewAndroid::SetContentViewCore(
|
|
|
| bool resize = false;
|
| if (content_view_core != content_view_core_) {
|
| + selection_controller_.reset();
|
| ReleaseLocksOnSurface();
|
| resize = true;
|
| }
|
| @@ -1275,15 +1419,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() {
|
| @@ -1445,8 +1596,8 @@ SkColorType RenderWidgetHostViewAndroid::PreferredReadbackFormat() {
|
| }
|
|
|
| void RenderWidgetHostViewAndroid::ShowSelectionHandlesAutomatically() {
|
| - if (content_view_core_)
|
| - content_view_core_->ShowSelectionHandlesAutomatically();
|
| + if (selection_controller_)
|
| + selection_controller_->ShowSelectionHandlesAutomatically();
|
| }
|
|
|
| void RenderWidgetHostViewAndroid::SelectRange(
|
|
|