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

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

Issue 894193005: [Android] Use the platform SwipeRefreshLayout (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years, 8 months 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/command_line.h" 8 #include "base/command_line.h"
9 #include "cc/layers/layer.h" 9 #include "cc/layers/layer.h"
10 #include "cc/output/compositor_frame_metadata.h" 10 #include "cc/output/compositor_frame_metadata.h"
11 #include "content/browser/android/content_view_core_impl.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/browser/web_contents/web_contents_impl.h" 14 #include "content/browser/web_contents/web_contents_impl.h"
14 #include "content/common/input/did_overscroll_params.h" 15 #include "content/common/input/did_overscroll_params.h"
15 #include "content/public/browser/navigation_controller.h" 16 #include "content/public/browser/navigation_controller.h"
16 #include "content/public/browser/user_metrics.h" 17 #include "content/public/browser/user_metrics.h"
17 #include "content/public/common/content_switches.h" 18 #include "content/public/common/content_switches.h"
18 #include "third_party/WebKit/public/web/WebInputEvent.h" 19 #include "third_party/WebKit/public/web/WebInputEvent.h"
19 #include "ui/android/resources/resource_manager.h" 20 #include "ui/android/resources/resource_manager.h"
21 #include "ui/android/window_android.h"
20 #include "ui/android/window_android_compositor.h" 22 #include "ui/android/window_android_compositor.h"
21 #include "ui/base/l10n/l10n_util_android.h" 23 #include "ui/base/l10n/l10n_util_android.h"
22 24
23 namespace content { 25 namespace content {
24 namespace { 26 namespace {
25 27
26 // Used for conditional creation of EdgeEffect types for the overscroll glow. 28 // Used for conditional creation of EdgeEffect types for the overscroll glow.
27 const int kAndroidLSDKVersion = 21; 29 const int kAndroidLSDKVersion = 21;
28 30
29 // Default offset in dips from the top of the view beyond which the refresh
30 // action will be activated.
31 const int kDefaultRefreshDragTargetDips = 64;
32
33 // If the glow effect alpha is greater than this value, the refresh effect will 31 // If the glow effect alpha is greater than this value, the refresh effect will
34 // be suppressed. This value was experimentally determined to provide a 32 // be suppressed. This value was experimentally determined to provide a
35 // reasonable balance between avoiding accidental refresh activation and 33 // reasonable balance between avoiding accidental refresh activation and
36 // minimizing the wait required to refresh after the glow has been triggered. 34 // minimizing the wait required to refresh after the glow has been triggered.
37 const float kMinGlowAlphaToDisableRefreshOnL = 0.085f; 35 const float kMinGlowAlphaToDisableRefreshOnL = 0.085f;
38 36
39 bool IsAndroidLOrNewer() { 37 bool IsAndroidLOrNewer() {
40 static bool android_l_or_newer = 38 static bool android_l_or_newer =
41 base::android::BuildInfo::GetInstance()->sdk_int() >= kAndroidLSDKVersion; 39 base::android::BuildInfo::GetInstance()->sdk_int() >= kAndroidLSDKVersion;
42 return android_l_or_newer; 40 return android_l_or_newer;
(...skipping 29 matching lines...) Expand all
72 float dpi_scale) { 70 float dpi_scale) {
73 if (base::CommandLine::ForCurrentProcess()->HasSwitch( 71 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
74 switches::kDisableOverscrollEdgeEffect)) { 72 switches::kDisableOverscrollEdgeEffect)) {
75 return nullptr; 73 return nullptr;
76 } 74 }
77 75
78 return make_scoped_ptr(new OverscrollGlow(client)); 76 return make_scoped_ptr(new OverscrollGlow(client));
79 } 77 }
80 78
81 scoped_ptr<OverscrollRefresh> CreateRefreshEffect( 79 scoped_ptr<OverscrollRefresh> CreateRefreshEffect(
82 ui::WindowAndroidCompositor* compositor, 80 OverscrollRefreshHandler* handler) {
83 OverscrollRefreshClient* client,
84 float dpi_scale) {
85 if (base::CommandLine::ForCurrentProcess()->HasSwitch( 81 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
86 switches::kDisablePullToRefreshEffect)) { 82 switches::kDisablePullToRefreshEffect)) {
87 return nullptr; 83 return nullptr;
88 } 84 }
89 85
90 return make_scoped_ptr(new OverscrollRefresh( 86 return make_scoped_ptr(new OverscrollRefresh(handler));
91 &compositor->GetResourceManager(), client,
92 kDefaultRefreshDragTargetDips * dpi_scale, l10n_util::IsLayoutRtl()));
93 } 87 }
94 88
95 } // namespace 89 } // namespace
96 90
97 OverscrollControllerAndroid::OverscrollControllerAndroid( 91 OverscrollControllerAndroid::OverscrollControllerAndroid(
98 WebContents* web_contents, 92 ContentViewCoreImpl* content_view_core)
99 ui::WindowAndroidCompositor* compositor, 93 : compositor_(content_view_core->GetWindowAndroid()->GetCompositor()),
100 float dpi_scale) 94 dpi_scale_(content_view_core->GetDpiScale()),
101 : compositor_(compositor),
102 dpi_scale_(dpi_scale),
103 enabled_(true), 95 enabled_(true),
104 glow_effect_(CreateGlowEffect(this, dpi_scale)), 96 glow_effect_(CreateGlowEffect(this, dpi_scale_)),
105 refresh_effect_(CreateRefreshEffect(compositor, this, dpi_scale)), 97 refresh_effect_(CreateRefreshEffect(content_view_core)),
106 triggered_refresh_active_(false), 98 is_fullscreen_(false) {
107 is_fullscreen_(static_cast<WebContentsImpl*>(web_contents) 99 DCHECK(compositor_);
108 ->IsFullscreenForCurrentTab()) {
109 DCHECK(web_contents);
110 DCHECK(compositor);
111 if (refresh_effect_)
112 Observe(web_contents);
113 } 100 }
114 101
115 OverscrollControllerAndroid::~OverscrollControllerAndroid() { 102 OverscrollControllerAndroid::~OverscrollControllerAndroid() {
116 } 103 }
117 104
118 bool OverscrollControllerAndroid::WillHandleGestureEvent( 105 bool OverscrollControllerAndroid::WillHandleGestureEvent(
119 const blink::WebGestureEvent& event) { 106 const blink::WebGestureEvent& event) {
120 if (!enabled_) 107 if (!enabled_)
121 return false; 108 return false;
122 109
123 if (!refresh_effect_) 110 if (!refresh_effect_)
124 return false; 111 return false;
125 112
126 // Suppress refresh detection for fullscreen HTML5 scenarios, e.g., video. 113 // Suppress refresh detection for fullscreen HTML5 scenarios, e.g., video.
127 if (is_fullscreen_) 114 if (is_fullscreen_)
128 return false; 115 return false;
129 116
130 // Suppress refresh detection if the glow effect is still prominent. 117 // Suppress refresh detection if the glow effect is still prominent.
131 if (glow_effect_ && glow_effect_->IsActive()) { 118 if (glow_effect_ && glow_effect_->IsActive()) {
132 if (glow_effect_->GetVisibleAlpha() > MinGlowAlphaToDisableRefresh()) 119 if (glow_effect_->GetVisibleAlpha() > MinGlowAlphaToDisableRefresh())
133 return false; 120 return false;
134 } 121 }
135 122
136 bool handled = false; 123 bool handled = false;
137 bool maybe_needs_animate = false;
138 switch (event.type) { 124 switch (event.type) {
139 case blink::WebInputEvent::GestureScrollBegin: 125 case blink::WebInputEvent::GestureScrollBegin:
140 refresh_effect_->OnScrollBegin(); 126 refresh_effect_->OnScrollBegin();
141 break; 127 break;
142 128
143 case blink::WebInputEvent::GestureScrollUpdate: { 129 case blink::WebInputEvent::GestureScrollUpdate: {
144 gfx::Vector2dF scroll_delta(event.data.scrollUpdate.deltaX, 130 gfx::Vector2dF scroll_delta(event.data.scrollUpdate.deltaX,
145 event.data.scrollUpdate.deltaY); 131 event.data.scrollUpdate.deltaY);
146 scroll_delta.Scale(dpi_scale_); 132 scroll_delta.Scale(dpi_scale_);
147 maybe_needs_animate = true;
148 handled = refresh_effect_->WillHandleScrollUpdate(scroll_delta); 133 handled = refresh_effect_->WillHandleScrollUpdate(scroll_delta);
149 } break; 134 } break;
150 135
151 case blink::WebInputEvent::GestureScrollEnd: 136 case blink::WebInputEvent::GestureScrollEnd:
152 refresh_effect_->OnScrollEnd(gfx::Vector2dF()); 137 refresh_effect_->OnScrollEnd(gfx::Vector2dF());
153 maybe_needs_animate = true;
154 break; 138 break;
155 139
156 case blink::WebInputEvent::GestureFlingStart: { 140 case blink::WebInputEvent::GestureFlingStart: {
157 gfx::Vector2dF scroll_velocity(event.data.flingStart.velocityX,
158 event.data.flingStart.velocityY);
159 scroll_velocity.Scale(dpi_scale_);
160 refresh_effect_->OnScrollEnd(scroll_velocity);
161 if (refresh_effect_->IsActive()) { 141 if (refresh_effect_->IsActive()) {
142 gfx::Vector2dF scroll_velocity(event.data.flingStart.velocityX,
143 event.data.flingStart.velocityY);
144 scroll_velocity.Scale(dpi_scale_);
145 refresh_effect_->OnScrollEnd(scroll_velocity);
162 // TODO(jdduke): Figure out a cleaner way of suppressing a fling. 146 // TODO(jdduke): Figure out a cleaner way of suppressing a fling.
163 // It's important that the any downstream code sees a scroll-ending 147 // It's important that the any downstream code sees a scroll-ending
164 // event (in this case GestureFlingStart) if it has seen a scroll begin. 148 // event (in this case GestureFlingStart) if it has seen a scroll begin.
165 // Thus, we cannot simply consume the fling. Changing the event type to 149 // Thus, we cannot simply consume the fling. Changing the event type to
166 // a GestureScrollEnd might work in practice, but could lead to 150 // a GestureScrollEnd might work in practice, but could lead to
167 // unexpected results. For now, simply truncate the fling velocity, but 151 // unexpected results. For now, simply truncate the fling velocity, but
168 // not to zero as downstream code may not expect a zero-velocity fling. 152 // not to zero as downstream code may not expect a zero-velocity fling.
169 blink::WebGestureEvent& modified_event = 153 blink::WebGestureEvent& modified_event =
170 const_cast<blink::WebGestureEvent&>(event); 154 const_cast<blink::WebGestureEvent&>(event);
171 modified_event.data.flingStart.velocityX = .01f; 155 modified_event.data.flingStart.velocityX = .01f;
172 modified_event.data.flingStart.velocityY = .01f; 156 modified_event.data.flingStart.velocityY = .01f;
173 } 157 }
174 maybe_needs_animate = true;
175 } break; 158 } break;
176 159
177 case blink::WebInputEvent::GesturePinchBegin: 160 case blink::WebInputEvent::GesturePinchBegin:
178 refresh_effect_->ReleaseWithoutActivation(); 161 refresh_effect_->ReleaseWithoutActivation();
179 break; 162 break;
180 163
181 default: 164 default:
182 break; 165 break;
183 } 166 }
184 167
185 if (maybe_needs_animate && refresh_effect_->IsActive())
186 SetNeedsAnimate();
187
188 return handled; 168 return handled;
189 } 169 }
190 170
191 void OverscrollControllerAndroid::OnGestureEventAck( 171 void OverscrollControllerAndroid::OnGestureEventAck(
192 const blink::WebGestureEvent& event, 172 const blink::WebGestureEvent& event,
193 InputEventAckState ack_result) { 173 InputEventAckState ack_result) {
194 if (!enabled_) 174 if (!enabled_)
195 return; 175 return;
196 176
197 // The overscroll effect requires an explicit release signal that may not be 177 // The overscroll effect requires an explicit release signal that may not be
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 SetNeedsAnimate(); 215 SetNeedsAnimate();
236 } 216 }
237 } 217 }
238 218
239 bool OverscrollControllerAndroid::Animate(base::TimeTicks current_time, 219 bool OverscrollControllerAndroid::Animate(base::TimeTicks current_time,
240 cc::Layer* parent_layer) { 220 cc::Layer* parent_layer) {
241 DCHECK(parent_layer); 221 DCHECK(parent_layer);
242 if (!enabled_) 222 if (!enabled_)
243 return false; 223 return false;
244 224
245 bool needs_animate = false; 225 return glow_effect_->Animate(current_time, parent_layer);
246 if (refresh_effect_)
247 needs_animate |= refresh_effect_->Animate(current_time, parent_layer);
248 if (glow_effect_)
249 needs_animate |= glow_effect_->Animate(current_time, parent_layer);
250 return needs_animate;
251 } 226 }
252 227
253 void OverscrollControllerAndroid::OnFrameMetadataUpdated( 228 void OverscrollControllerAndroid::OnFrameMetadataUpdated(
254 const cc::CompositorFrameMetadata& frame_metadata) { 229 const cc::CompositorFrameMetadata& frame_metadata) {
255 if (!refresh_effect_ && !glow_effect_) 230 if (!refresh_effect_ && !glow_effect_)
256 return; 231 return;
257 232
258 const float scale_factor = 233 const float scale_factor =
259 frame_metadata.page_scale_factor * frame_metadata.device_scale_factor; 234 frame_metadata.page_scale_factor * frame_metadata.device_scale_factor;
260 gfx::SizeF viewport_size = 235 gfx::SizeF viewport_size =
261 gfx::ScaleSize(frame_metadata.scrollable_viewport_size, scale_factor); 236 gfx::ScaleSize(frame_metadata.scrollable_viewport_size, scale_factor);
262 gfx::SizeF content_size = 237 gfx::SizeF content_size =
263 gfx::ScaleSize(frame_metadata.root_layer_size, scale_factor); 238 gfx::ScaleSize(frame_metadata.root_layer_size, scale_factor);
264 gfx::Vector2dF content_scroll_offset = 239 gfx::Vector2dF content_scroll_offset =
265 gfx::ScaleVector2d(frame_metadata.root_scroll_offset, scale_factor); 240 gfx::ScaleVector2d(frame_metadata.root_scroll_offset, scale_factor);
266 241
267 if (refresh_effect_) { 242 if (refresh_effect_) {
268 refresh_effect_->UpdateDisplay(viewport_size, content_scroll_offset, 243 refresh_effect_->OnFrameUpdated(content_scroll_offset,
269 frame_metadata.root_overflow_y_hidden); 244 frame_metadata.root_overflow_y_hidden);
270 } 245 }
271 246
272 if (glow_effect_) { 247 if (glow_effect_) {
273 glow_effect_->UpdateDisplay(viewport_size, content_size, 248 glow_effect_->OnFrameUpdated(viewport_size, content_size,
274 content_scroll_offset); 249 content_scroll_offset);
275 } 250 }
276 } 251 }
277 252
278 void OverscrollControllerAndroid::Enable() { 253 void OverscrollControllerAndroid::Enable() {
279 enabled_ = true; 254 enabled_ = true;
280 } 255 }
281 256
282 void OverscrollControllerAndroid::Disable() { 257 void OverscrollControllerAndroid::Disable() {
283 if (!enabled_) 258 if (!enabled_)
284 return; 259 return;
285 enabled_ = false; 260 enabled_ = false;
286 if (!enabled_) { 261 if (!enabled_) {
287 if (refresh_effect_) 262 if (refresh_effect_)
288 refresh_effect_->Reset(); 263 refresh_effect_->Reset();
289 if (glow_effect_) 264 if (glow_effect_)
290 glow_effect_->Reset(); 265 glow_effect_->Reset();
291 } 266 }
292 } 267 }
293 268
294 void OverscrollControllerAndroid::DidNavigateMainFrame(
295 const LoadCommittedDetails& details,
296 const FrameNavigateParams& params) {
297 // Once the main frame has navigated, there's little need to further animate
298 // the reload effect. Note that the effect will naturally time out should the
299 // reload be interruped for any reason.
300 triggered_refresh_active_ = false;
301 }
302
303 void OverscrollControllerAndroid::DidToggleFullscreenModeForTab( 269 void OverscrollControllerAndroid::DidToggleFullscreenModeForTab(
304 bool entered_fullscreen) { 270 bool entered_fullscreen) {
305 if (is_fullscreen_ == entered_fullscreen) 271 if (is_fullscreen_ == entered_fullscreen)
306 return; 272 return;
307 is_fullscreen_ = entered_fullscreen; 273 is_fullscreen_ = entered_fullscreen;
308 if (is_fullscreen_) 274 if (is_fullscreen_)
309 refresh_effect_->ReleaseWithoutActivation(); 275 refresh_effect_->ReleaseWithoutActivation();
310 } 276 }
311 277
312 void OverscrollControllerAndroid::TriggerRefresh() {
313 triggered_refresh_active_ = false;
314 if (!web_contents())
315 return;
316
317 triggered_refresh_active_ = true;
318 RecordAction(base::UserMetricsAction("MobilePullGestureReload"));
319 web_contents()->GetController().Reload(true);
320 }
321
322 bool OverscrollControllerAndroid::IsStillRefreshing() const {
323 return triggered_refresh_active_;
324 }
325
326 scoped_ptr<EdgeEffectBase> OverscrollControllerAndroid::CreateEdgeEffect() { 278 scoped_ptr<EdgeEffectBase> OverscrollControllerAndroid::CreateEdgeEffect() {
327 return CreateGlowEdgeEffect(&compositor_->GetResourceManager(), dpi_scale_); 279 return CreateGlowEdgeEffect(&compositor_->GetResourceManager(), dpi_scale_);
328 } 280 }
329 281
330 void OverscrollControllerAndroid::SetNeedsAnimate() { 282 void OverscrollControllerAndroid::SetNeedsAnimate() {
331 compositor_->SetNeedsAnimate(); 283 compositor_->SetNeedsAnimate();
332 } 284 }
333 285
334 } // namespace content 286 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/android/overscroll_controller_android.h ('k') | content/browser/android/overscroll_glow.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698