Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2996)

Side by Side Diff: content/browser/android/overscroll_controller_android.cc

Issue 733293002: [Android] Add a flag to disable the pull-to-refresh effect (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Code review and histograms.xml Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/android/overscroll_controller_android.h" 5 #include "content/browser/android/overscroll_controller_android.h"
6 6
7 #include "base/android/build_info.h" 7 #include "base/android/build_info.h"
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "base/command_line.h"
9 #include "cc/layers/layer.h" 10 #include "cc/layers/layer.h"
10 #include "cc/output/compositor_frame_metadata.h" 11 #include "cc/output/compositor_frame_metadata.h"
11 #include "content/browser/android/edge_effect.h" 12 #include "content/browser/android/edge_effect.h"
12 #include "content/browser/android/edge_effect_l.h" 13 #include "content/browser/android/edge_effect_l.h"
13 #include "content/common/input/did_overscroll_params.h" 14 #include "content/common/input/did_overscroll_params.h"
14 #include "content/public/browser/web_contents.h" 15 #include "content/public/browser/web_contents.h"
16 #include "content/public/common/content_switches.h"
15 #include "third_party/WebKit/public/web/WebInputEvent.h" 17 #include "third_party/WebKit/public/web/WebInputEvent.h"
16 #include "ui/base/android/window_android_compositor.h" 18 #include "ui/base/android/window_android_compositor.h"
17 19
18 namespace content { 20 namespace content {
19 namespace { 21 namespace {
20 22
21 // Used for conditional creation of EdgeEffect types for the overscroll glow. 23 // Used for conditional creation of EdgeEffect types for the overscroll glow.
22 const int kAndroidLSDKVersion = 21; 24 const int kAndroidLSDKVersion = 21;
23 25
24 scoped_ptr<EdgeEffectBase> CreateGlowEdgeEffect( 26 scoped_ptr<EdgeEffectBase> CreateGlowEdgeEffect(
25 ui::SystemUIResourceManager* resource_manager, 27 ui::SystemUIResourceManager* resource_manager,
26 float dpi_scale) { 28 float dpi_scale) {
27 DCHECK(resource_manager); 29 DCHECK(resource_manager);
28 static bool use_l_flavoured_effect = 30 static bool use_l_flavoured_effect =
29 base::android::BuildInfo::GetInstance()->sdk_int() >= kAndroidLSDKVersion; 31 base::android::BuildInfo::GetInstance()->sdk_int() >= kAndroidLSDKVersion;
30 if (use_l_flavoured_effect) 32 if (use_l_flavoured_effect)
31 return scoped_ptr<EdgeEffectBase>(new EdgeEffectL(resource_manager)); 33 return scoped_ptr<EdgeEffectBase>(new EdgeEffectL(resource_manager));
32 34
33 return scoped_ptr<EdgeEffectBase>( 35 return scoped_ptr<EdgeEffectBase>(
34 new EdgeEffect(resource_manager, dpi_scale)); 36 new EdgeEffect(resource_manager, dpi_scale));
35 } 37 }
36 38
39 scoped_ptr<OverscrollGlow> CreateGlowEffect(
40 ui::WindowAndroidCompositor* compositor,
41 float dpi_scale) {
42 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
43 switches::kDisableOverscrollEdgeEffect)) {
44 return scoped_ptr<OverscrollGlow>();
boliu 2014/11/20 23:12:48 return nullptr should work, the new c++11 hotness
jdduke (slow) 2014/11/20 23:14:54 yay!
45 }
46
47 return make_scoped_ptr(new OverscrollGlow(
48 base::Bind(&CreateGlowEdgeEffect,
49 &compositor->GetSystemUIResourceManager(), dpi_scale)));
50 }
51
52 scoped_ptr<OverscrollRefresh> CreateRefreshEffect(
53 ui::WindowAndroidCompositor* compositor,
54 OverscrollRefreshClient* client) {
55 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
56 switches::kDisablePullToRefreshEffect)) {
57 return scoped_ptr<OverscrollRefresh>();
boliu 2014/11/20 23:12:48 ditto
jdduke (slow) 2014/11/20 23:14:54 Done.
58 }
59
60 return make_scoped_ptr(
61 new OverscrollRefresh(&compositor->GetSystemUIResourceManager(), client));
62 }
63
37 } // namespace 64 } // namespace
38 65
39 OverscrollControllerAndroid::OverscrollControllerAndroid( 66 OverscrollControllerAndroid::OverscrollControllerAndroid(
40 WebContents* web_contents, 67 WebContents* web_contents,
41 ui::WindowAndroidCompositor* compositor, 68 ui::WindowAndroidCompositor* compositor,
42 float dpi_scale) 69 float dpi_scale)
43 : WebContentsObserver(web_contents), 70 : compositor_(compositor),
44 compositor_(compositor),
45 dpi_scale_(dpi_scale), 71 dpi_scale_(dpi_scale),
46 enabled_(true), 72 enabled_(true),
47 glow_effect_(base::Bind(&CreateGlowEdgeEffect, 73 glow_effect_(CreateGlowEffect(compositor, dpi_scale)),
48 &compositor->GetSystemUIResourceManager(), 74 refresh_effect_(CreateRefreshEffect(compositor, this)),
49 dpi_scale_)),
50 refresh_effect_(&compositor->GetSystemUIResourceManager(), this),
51 triggered_refresh_active_(false) { 75 triggered_refresh_active_(false) {
52 DCHECK(web_contents); 76 DCHECK(web_contents);
77 DCHECK(compositor);
78 if (refresh_effect_)
79 Observe(web_contents);
53 } 80 }
54 81
55 OverscrollControllerAndroid::~OverscrollControllerAndroid() { 82 OverscrollControllerAndroid::~OverscrollControllerAndroid() {
56 } 83 }
57 84
58 bool OverscrollControllerAndroid::WillHandleGestureEvent( 85 bool OverscrollControllerAndroid::WillHandleGestureEvent(
59 const blink::WebGestureEvent& event) { 86 const blink::WebGestureEvent& event) {
60 if (!enabled_) 87 if (!enabled_)
61 return false; 88 return false;
62 89
90 if (!refresh_effect_)
91 return false;
92
63 bool handled = false; 93 bool handled = false;
64 bool maybe_needs_animate = false; 94 bool maybe_needs_animate = false;
65 switch (event.type) { 95 switch (event.type) {
66 case blink::WebInputEvent::GestureScrollBegin: 96 case blink::WebInputEvent::GestureScrollBegin:
67 refresh_effect_.OnScrollBegin(); 97 refresh_effect_->OnScrollBegin();
68 break; 98 break;
69 99
70 case blink::WebInputEvent::GestureScrollUpdate: { 100 case blink::WebInputEvent::GestureScrollUpdate: {
71 gfx::Vector2dF scroll_delta(event.data.scrollUpdate.deltaX, 101 gfx::Vector2dF scroll_delta(event.data.scrollUpdate.deltaX,
72 event.data.scrollUpdate.deltaY); 102 event.data.scrollUpdate.deltaY);
73 scroll_delta.Scale(dpi_scale_); 103 scroll_delta.Scale(dpi_scale_);
74 maybe_needs_animate = true; 104 maybe_needs_animate = true;
75 handled = refresh_effect_.WillHandleScrollUpdate(scroll_delta); 105 handled = refresh_effect_->WillHandleScrollUpdate(scroll_delta);
76 } break; 106 } break;
77 107
78 case blink::WebInputEvent::GestureScrollEnd: 108 case blink::WebInputEvent::GestureScrollEnd:
79 refresh_effect_.OnScrollEnd(gfx::Vector2dF()); 109 refresh_effect_->OnScrollEnd(gfx::Vector2dF());
80 maybe_needs_animate = true; 110 maybe_needs_animate = true;
81 break; 111 break;
82 112
83 case blink::WebInputEvent::GestureFlingStart: { 113 case blink::WebInputEvent::GestureFlingStart: {
84 gfx::Vector2dF scroll_velocity(event.data.flingStart.velocityX, 114 gfx::Vector2dF scroll_velocity(event.data.flingStart.velocityX,
85 event.data.flingStart.velocityY); 115 event.data.flingStart.velocityY);
86 scroll_velocity.Scale(dpi_scale_); 116 scroll_velocity.Scale(dpi_scale_);
87 refresh_effect_.OnScrollEnd(scroll_velocity); 117 refresh_effect_->OnScrollEnd(scroll_velocity);
88 if (refresh_effect_.IsActive()) { 118 if (refresh_effect_->IsActive()) {
89 // TODO(jdduke): Figure out a cleaner way of suppressing a fling. 119 // TODO(jdduke): Figure out a cleaner way of suppressing a fling.
90 // It's important that the any downstream code sees a scroll-ending 120 // It's important that the any downstream code sees a scroll-ending
91 // event (in this case GestureFlingStart) if it has seen a scroll begin. 121 // event (in this case GestureFlingStart) if it has seen a scroll begin.
92 // Thus, we cannot simply consume the fling. Changing the event type to 122 // Thus, we cannot simply consume the fling. Changing the event type to
93 // a GestureScrollEnd might work in practice, but could lead to 123 // a GestureScrollEnd might work in practice, but could lead to
94 // unexpected results. For now, simply truncate the fling velocity, but 124 // unexpected results. For now, simply truncate the fling velocity, but
95 // not to zero as downstream code may not expect a zero-velocity fling. 125 // not to zero as downstream code may not expect a zero-velocity fling.
96 blink::WebGestureEvent& modified_event = 126 blink::WebGestureEvent& modified_event =
97 const_cast<blink::WebGestureEvent&>(event); 127 const_cast<blink::WebGestureEvent&>(event);
98 modified_event.data.flingStart.velocityX = .01f; 128 modified_event.data.flingStart.velocityX = .01f;
99 modified_event.data.flingStart.velocityY = .01f; 129 modified_event.data.flingStart.velocityY = .01f;
100 } 130 }
101 maybe_needs_animate = true; 131 maybe_needs_animate = true;
102 } break; 132 } break;
103 133
104 default: 134 default:
105 break; 135 break;
106 } 136 }
107 137
108 if (maybe_needs_animate && refresh_effect_.IsActive()) 138 if (maybe_needs_animate && refresh_effect_->IsActive())
109 SetNeedsAnimate(); 139 SetNeedsAnimate();
110 140
111 return handled; 141 return handled;
112 } 142 }
113 143
114 void OverscrollControllerAndroid::OnGestureEventAck( 144 void OverscrollControllerAndroid::OnGestureEventAck(
115 const blink::WebGestureEvent& event, 145 const blink::WebGestureEvent& event,
116 InputEventAckState ack_result) { 146 InputEventAckState ack_result) {
117 if (!enabled_) 147 if (!enabled_)
118 return; 148 return;
119 149
120 // The overscroll effect requires an explicit release signal that may not be 150 // The overscroll effect requires an explicit release signal that may not be
121 // sent from the renderer compositor. 151 // sent from the renderer compositor.
122 if (event.type == blink::WebInputEvent::GestureScrollEnd || 152 if (event.type == blink::WebInputEvent::GestureScrollEnd ||
123 event.type == blink::WebInputEvent::GestureFlingStart) { 153 event.type == blink::WebInputEvent::GestureFlingStart) {
124 OnOverscrolled(DidOverscrollParams()); 154 OnOverscrolled(DidOverscrollParams());
125 } 155 }
126 156
127 if (event.type == blink::WebInputEvent::GestureScrollUpdate) { 157 if (event.type == blink::WebInputEvent::GestureScrollUpdate &&
158 refresh_effect_) {
128 // The effect should only be allowed if both the causal touch events go 159 // The effect should only be allowed if both the causal touch events go
129 // unconsumed and the generated scroll events go unconsumed. 160 // unconsumed and the generated scroll events go unconsumed.
130 bool consumed = ack_result == INPUT_EVENT_ACK_STATE_CONSUMED || 161 bool consumed = ack_result == INPUT_EVENT_ACK_STATE_CONSUMED ||
131 event.data.scrollUpdate.previousUpdateInSequencePrevented; 162 event.data.scrollUpdate.previousUpdateInSequencePrevented;
132 refresh_effect_.OnScrollUpdateAck(consumed); 163 refresh_effect_->OnScrollUpdateAck(consumed);
133 } 164 }
134 } 165 }
135 166
136 void OverscrollControllerAndroid::OnOverscrolled( 167 void OverscrollControllerAndroid::OnOverscrolled(
137 const DidOverscrollParams& params) { 168 const DidOverscrollParams& params) {
138 if (!enabled_) 169 if (!enabled_)
139 return; 170 return;
140 171
141 if (refresh_effect_.IsActive() || 172 if (refresh_effect_ &&
142 refresh_effect_.IsAwaitingScrollUpdateAck()) { 173 (refresh_effect_->IsActive() ||
174 refresh_effect_->IsAwaitingScrollUpdateAck())) {
143 // An active (or potentially active) refresh effect should always pre-empt 175 // An active (or potentially active) refresh effect should always pre-empt
144 // the passive glow effect. 176 // the passive glow effect.
145 return; 177 return;
146 } 178 }
147 179
148 if (glow_effect_.OnOverscrolled( 180 if (glow_effect_ &&
181 glow_effect_->OnOverscrolled(
149 base::TimeTicks::Now(), 182 base::TimeTicks::Now(),
150 gfx::ScaleVector2d(params.accumulated_overscroll, dpi_scale_), 183 gfx::ScaleVector2d(params.accumulated_overscroll, dpi_scale_),
151 gfx::ScaleVector2d(params.latest_overscroll_delta, dpi_scale_), 184 gfx::ScaleVector2d(params.latest_overscroll_delta, dpi_scale_),
152 gfx::ScaleVector2d(params.current_fling_velocity, dpi_scale_), 185 gfx::ScaleVector2d(params.current_fling_velocity, dpi_scale_),
153 gfx::ScaleVector2d(params.causal_event_viewport_point.OffsetFromOrigin(), 186 gfx::ScaleVector2d(params.causal_event_viewport_point.OffsetFromOrigin(),
154 dpi_scale_))) { 187 dpi_scale_))) {
155 SetNeedsAnimate(); 188 SetNeedsAnimate();
156 } 189 }
157 } 190 }
158 191
159 bool OverscrollControllerAndroid::Animate(base::TimeTicks current_time, 192 bool OverscrollControllerAndroid::Animate(base::TimeTicks current_time,
160 cc::Layer* parent_layer) { 193 cc::Layer* parent_layer) {
161 DCHECK(parent_layer); 194 DCHECK(parent_layer);
162 if (!enabled_) 195 if (!enabled_)
163 return false; 196 return false;
164 197
165 bool needs_animate = refresh_effect_.Animate(current_time, parent_layer); 198 bool needs_animate = false;
166 needs_animate |= glow_effect_.Animate(current_time, parent_layer); 199 if (refresh_effect_)
200 needs_animate |= refresh_effect_->Animate(current_time, parent_layer);
201 if (glow_effect_)
202 needs_animate |= glow_effect_->Animate(current_time, parent_layer);
167 return needs_animate; 203 return needs_animate;
168 } 204 }
169 205
170 void OverscrollControllerAndroid::OnFrameMetadataUpdated( 206 void OverscrollControllerAndroid::OnFrameMetadataUpdated(
171 const cc::CompositorFrameMetadata& frame_metadata) { 207 const cc::CompositorFrameMetadata& frame_metadata) {
208 if (!refresh_effect_ && !glow_effect_)
209 return;
210
172 const float scale_factor = 211 const float scale_factor =
173 frame_metadata.page_scale_factor * frame_metadata.device_scale_factor; 212 frame_metadata.page_scale_factor * frame_metadata.device_scale_factor;
174 gfx::SizeF viewport_size = 213 gfx::SizeF viewport_size =
175 gfx::ScaleSize(frame_metadata.scrollable_viewport_size, scale_factor); 214 gfx::ScaleSize(frame_metadata.scrollable_viewport_size, scale_factor);
176 gfx::SizeF content_size = 215 gfx::SizeF content_size =
177 gfx::ScaleSize(frame_metadata.root_layer_size, scale_factor); 216 gfx::ScaleSize(frame_metadata.root_layer_size, scale_factor);
178 gfx::Vector2dF content_scroll_offset = 217 gfx::Vector2dF content_scroll_offset =
179 gfx::ScaleVector2d(frame_metadata.root_scroll_offset, scale_factor); 218 gfx::ScaleVector2d(frame_metadata.root_scroll_offset, scale_factor);
180 219
181 refresh_effect_.UpdateDisplay(viewport_size, content_scroll_offset); 220 if (refresh_effect_)
182 glow_effect_.UpdateDisplay(viewport_size, content_size, 221 refresh_effect_->UpdateDisplay(viewport_size, content_scroll_offset);
183 content_scroll_offset); 222
223 if (glow_effect_) {
224 glow_effect_->UpdateDisplay(viewport_size, content_size,
225 content_scroll_offset);
226 }
184 } 227 }
185 228
186 void OverscrollControllerAndroid::Enable() { 229 void OverscrollControllerAndroid::Enable() {
187 enabled_ = true; 230 enabled_ = true;
188 } 231 }
189 232
190 void OverscrollControllerAndroid::Disable() { 233 void OverscrollControllerAndroid::Disable() {
191 if (!enabled_) 234 if (!enabled_)
192 return; 235 return;
193 enabled_ = false; 236 enabled_ = false;
194 if (!enabled_) { 237 if (!enabled_) {
195 refresh_effect_.Reset(); 238 if (refresh_effect_)
196 glow_effect_.Reset(); 239 refresh_effect_->Reset();
240 if (glow_effect_)
241 glow_effect_->Reset();
197 } 242 }
198 } 243 }
199 244
200 void OverscrollControllerAndroid::DidNavigateMainFrame( 245 void OverscrollControllerAndroid::DidNavigateMainFrame(
201 const LoadCommittedDetails& details, 246 const LoadCommittedDetails& details,
202 const FrameNavigateParams& params) { 247 const FrameNavigateParams& params) {
203 // Once the main frame has navigated, there's little need to further animate 248 // Once the main frame has navigated, there's little need to further animate
204 // the reload effect. Note that the effect will naturally time out should the 249 // the reload effect. Note that the effect will naturally time out should the
205 // reload be interruped for any reason. 250 // reload be interruped for any reason.
206 triggered_refresh_active_ = false; 251 triggered_refresh_active_ = false;
(...skipping 10 matching lines...) Expand all
217 262
218 bool OverscrollControllerAndroid::IsStillRefreshing() const { 263 bool OverscrollControllerAndroid::IsStillRefreshing() const {
219 return triggered_refresh_active_; 264 return triggered_refresh_active_;
220 } 265 }
221 266
222 void OverscrollControllerAndroid::SetNeedsAnimate() { 267 void OverscrollControllerAndroid::SetNeedsAnimate() {
223 compositor_->SetNeedsAnimate(); 268 compositor_->SetNeedsAnimate();
224 } 269 }
225 270
226 } // namespace content 271 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/android/overscroll_controller_android.h ('k') | content/browser/renderer_host/render_process_host_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698