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 1597e00b40a6faf85ce01de466303f514f2d404c..7ba2f80504313961ad9464aba0313907cc6af20e 100644 |
--- a/content/browser/renderer_host/render_widget_host_view_android.cc |
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc |
@@ -15,6 +15,7 @@ |
#include "cc/output/compositor_frame.h" |
#include "cc/output/compositor_frame_ack.h" |
#include "content/browser/android/content_view_core_impl.h" |
+#include "content/browser/android/overscroll_glow.h" |
#include "content/browser/gpu/gpu_surface_tracker.h" |
#include "content/browser/renderer_host/compositor_impl_android.h" |
#include "content/browser/renderer_host/image_transport_factory_android.h" |
@@ -67,17 +68,30 @@ void InsertSyncPointAndAckForCompositor( |
route_id, renderer_host_id, ack); |
} |
+scoped_ptr<OverscrollGlow> CreateOverscrollEffect( |
+ ContentViewCoreImpl* content_view_core){ |
+ if (content_view_core != NULL && |
+ !content_view_core->get_overscroll_edge().isNull() && |
+ !content_view_core->get_overscroll_glow().isNull()) { |
+ return make_scoped_ptr( |
+ new OverscrollGlow(content_view_core->get_overscroll_edge(), |
+ content_view_core->get_overscroll_glow())); |
+ } |
+ return scoped_ptr<OverscrollGlow>(); |
+} |
+ |
} // anonymous namespace |
RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid( |
RenderWidgetHostImpl* widget_host, |
ContentViewCoreImpl* content_view_core) |
: host_(widget_host), |
- is_layer_attached_(true), |
+ are_layers_attached_(true), |
content_view_core_(NULL), |
ime_adapter_android_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
cached_background_color_(SK_ColorWHITE), |
- texture_id_in_layer_(0) { |
+ texture_id_in_layer_(0), |
+ overscroll_resources_updated_(true) { |
if (CompositorImpl::UsesDirectGL()) { |
surface_texture_transport_.reset(new SurfaceTextureTransportClient()); |
layer_ = surface_texture_transport_->Initialize(); |
@@ -289,28 +303,26 @@ bool RenderWidgetHostViewAndroid::IsSurfaceAvailableForCopy() const { |
} |
void RenderWidgetHostViewAndroid::Show() { |
- if (is_layer_attached_) |
+ if (are_layers_attached_) |
return; |
- is_layer_attached_ = true; |
- if (content_view_core_) |
- content_view_core_->AttachLayer(layer_); |
+ are_layers_attached_ = true; |
+ AttachLayers(); |
} |
void RenderWidgetHostViewAndroid::Hide() { |
- if (!is_layer_attached_) |
+ if (!are_layers_attached_) |
return; |
- is_layer_attached_ = false; |
- if (content_view_core_) |
- content_view_core_->RemoveLayer(layer_); |
+ are_layers_attached_ = false; |
+ RemoveLayers(); |
} |
bool RenderWidgetHostViewAndroid::IsShowing() { |
// ContentViewCoreImpl represents the native side of the Java |
// ContentViewCore. It being NULL means that it is not attached |
// to the View system yet, so we treat this RWHVA as hidden. |
- return is_layer_attached_ && content_view_core_; |
+ return are_layers_attached_ && content_view_core_; |
} |
gfx::Rect RenderWidgetHostViewAndroid::GetViewBounds() const { |
@@ -391,6 +403,10 @@ void RenderWidgetHostViewAndroid::OnStartContentIntent( |
content_view_core_->StartContentIntent(content_url); |
} |
+void RenderWidgetHostViewAndroid::OnSetOverscrollResources() { |
+ overscroll_resources_updated_ = true; |
+} |
+ |
void RenderWidgetHostViewAndroid::ImeCancelComposition() { |
ime_adapter_android_.CancelComposition(); |
} |
@@ -413,10 +429,10 @@ void RenderWidgetHostViewAndroid::RenderViewGone( |
} |
void RenderWidgetHostViewAndroid::Destroy() { |
- if (content_view_core_) { |
- content_view_core_->RemoveLayer(layer_); |
- content_view_core_ = NULL; |
- } |
+ RemoveLayers(); |
+ content_view_core_ = NULL; |
+ |
+ overscroll_effect_.reset(); |
// The RenderWidgetHost's destruction led here, so don't call it. |
host_ = NULL; |
@@ -595,6 +611,13 @@ void RenderWidgetHostViewAndroid::BuffersSwapped( |
texture_layer_->SetBounds(gfx::Size(content_size.width(), |
content_size.height())); |
+ if (overscroll_resources_updated_) { |
+ SetOverscrollEffect(CreateOverscrollEffect(content_view_core_)); |
+ overscroll_resources_updated_ = false; |
+ } |
+ if (overscroll_effect_) |
+ overscroll_effect_->set_size(content_size); |
+ |
// Calculate the uv_max based on the content size relative to the texture |
// size. |
gfx::PointF uv_max; |
@@ -608,6 +631,50 @@ void RenderWidgetHostViewAndroid::BuffersSwapped( |
ack_callback.Run(); |
} |
+void RenderWidgetHostViewAndroid::AttachLayers() { |
+ if (!content_view_core_) |
+ return; |
+ |
+ content_view_core_->AttachLayer(layer_); |
+ |
+ if (overscroll_effect_) |
+ overscroll_effect_->set_parent_layer(content_view_core_->GetLayer()); |
+} |
+ |
+void RenderWidgetHostViewAndroid::RemoveLayers() { |
+ if (!content_view_core_) |
+ return; |
+ |
+ if (overscroll_effect_) |
+ overscroll_effect_->set_parent_layer(NULL); |
+ |
+ content_view_core_->RemoveLayer(layer_); |
+} |
+ |
+void RenderWidgetHostViewAndroid::SetOverscrollEffect( |
+ scoped_ptr<OverscrollGlow> overscroll_effect) { |
+ animation_timer_.Stop(); |
+ overscroll_effect_.swap(overscroll_effect); |
+ if (content_view_core_ && are_layers_attached_) |
+ overscroll_effect_->set_parent_layer(content_view_core_->GetLayer()); |
+} |
+ |
+void RenderWidgetHostViewAndroid::AnimationCallback() { |
+ if (overscroll_effect_ && overscroll_effect_->Animate(base::TimeTicks::Now())) |
+ AnimateIfNeeded(); |
+} |
+ |
+void RenderWidgetHostViewAndroid::AnimateIfNeeded() { |
+ if (animation_timer_.IsRunning() || !overscroll_effect_) |
+ return; |
+ |
+ const base::TimeDelta animationInterval |
+ = base::TimeDelta::FromMilliseconds(kDesiredAnimationIntervalInMs); |
+ |
+ animation_timer_.Start(FROM_HERE, animationInterval, this, |
+ &RenderWidgetHostViewAndroid::AnimationCallback); |
+} |
+ |
void RenderWidgetHostViewAndroid::AcceleratedSurfacePostSubBuffer( |
const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params, |
int gpu_host_id) { |
@@ -761,16 +828,32 @@ void RenderWidgetHostViewAndroid::UpdateFrameInfo( |
content_size, viewport_size, controls_offset, content_offset, |
overdraw_bottom_height); |
} |
+ |
+ if (overscroll_effect_) |
+ overscroll_effect_->set_horizontal_overscroll_enabled( |
+ content_size.width() != viewport_size.width()); |
+ |
+} |
+ |
+void RenderWidgetHostViewAndroid::OnOverscrolled( |
+ const gfx::Vector2dF& accumulated_overscroll, |
+ const gfx::Vector2dF& current_fling_velocity) { |
+ if (overscroll_effect_) { |
+ overscroll_effect_->OnOverscrolled(base::TimeTicks::Now(), |
+ accumulated_overscroll, |
+ current_fling_velocity); |
+ AnimateIfNeeded(); |
+ } |
} |
void RenderWidgetHostViewAndroid::SetContentViewCore( |
ContentViewCoreImpl* content_view_core) { |
- if (content_view_core_ && is_layer_attached_) |
- content_view_core_->RemoveLayer(layer_); |
+ if (are_layers_attached_) |
+ RemoveLayers(); |
content_view_core_ = content_view_core; |
- if (content_view_core_ && is_layer_attached_) |
- content_view_core_->AttachLayer(layer_); |
+ if (are_layers_attached_) |
+ AttachLayers(); |
} |
void RenderWidgetHostViewAndroid::HasTouchEventHandlers( |