1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/gesture_prefs_observer_factory_aura.h"
10 #include "base/bind_helpers.h"
11 #include "base/compiler_specific.h"
12 #include "base/prefs/pref_change_registrar.h"
13 #include "base/prefs/pref_service.h"
14 #include "chrome/browser/chrome_notification_types.h"
15 #include "chrome/browser/profiles/incognito_helpers.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/common/pref_names.h"
18 #include "components/browser_context_keyed_service/browser_context_dependency_manager.h"
19 #include "components/user_prefs/pref_registry_syncable.h"
20 #include "content/public/browser/notification_observer.h"
21 #include "content/public/browser/notification_service.h"
22 #include "content/public/browser/overscroll_configuration.h"
23 #include "content/public/common/renderer_preferences.h"
24 #include "ui/events/gestures/gesture_configuration.h"
26 using ui::GestureConfiguration
;
30 // TODO(rjkroege): Remove this deprecated pref in M29. http://crbug.com/160243.
31 const char kTouchScreenFlingAccelerationAdjustment
[] =
32 "gesture.touchscreen_fling_acceleration_adjustment";
34 struct OverscrollPref
{
35 const char* pref_name
;
36 content::OverscrollConfig config
;
39 const std::vector
<OverscrollPref
>& GetOverscrollPrefs() {
40 CR_DEFINE_STATIC_LOCAL(std::vector
<OverscrollPref
>, overscroll_prefs
, ());
41 if (overscroll_prefs
.empty()) {
42 using namespace content
;
43 const OverscrollPref kOverscrollPrefs
[] = {
44 { prefs::kOverscrollHorizontalThresholdComplete
,
45 OVERSCROLL_CONFIG_HORIZ_THRESHOLD_COMPLETE
},
46 { prefs::kOverscrollVerticalThresholdComplete
,
47 OVERSCROLL_CONFIG_VERT_THRESHOLD_COMPLETE
},
48 { prefs::kOverscrollMinimumThresholdStart
,
49 OVERSCROLL_CONFIG_HORIZ_THRESHOLD_START_TOUCHSCREEN
},
50 { prefs::kOverscrollMinimumThresholdStartTouchpad
,
51 OVERSCROLL_CONFIG_HORIZ_THRESHOLD_START_TOUCHPAD
},
52 { prefs::kOverscrollVerticalThresholdStart
,
53 OVERSCROLL_CONFIG_VERT_THRESHOLD_START
},
54 { prefs::kOverscrollHorizontalResistThreshold
,
55 OVERSCROLL_CONFIG_HORIZ_RESIST_AFTER
},
56 { prefs::kOverscrollVerticalResistThreshold
,
57 OVERSCROLL_CONFIG_VERT_RESIST_AFTER
},
59 overscroll_prefs
.assign(kOverscrollPrefs
,
60 kOverscrollPrefs
+ arraysize(kOverscrollPrefs
));
62 return overscroll_prefs
;
65 // This class manages gesture configuration preferences.
66 class GesturePrefsObserver
: public BrowserContextKeyedService
{
68 explicit GesturePrefsObserver(PrefService
* prefs
);
69 virtual ~GesturePrefsObserver();
71 // BrowserContextKeyedService implementation.
72 virtual void Shutdown() OVERRIDE
;
75 // Notification callback invoked when browser-side preferences
76 // are updated and need to be pushed into ui::GesturePreferences.
79 // Notification callback invoked when the fling deacceleration
80 // gesture preferences are changed from chrome://gesture.
81 // Broadcasts the changes all renderers where they are used.
84 // Notification helper to push overscroll preferences into
86 void UpdateOverscrollPrefs();
88 PrefChangeRegistrar registrar_
;
91 DISALLOW_COPY_AND_ASSIGN(GesturePrefsObserver
);
94 // The list of prefs we want to observe.
95 // Note that this collection of settings should correspond to the settings used
96 // in ui/events/gestures/gesture_configuration.h
97 const char* kPrefsToObserve
[] = {
98 prefs::kFlingAccelerationCurveCoefficient0
,
99 prefs::kFlingAccelerationCurveCoefficient1
,
100 prefs::kFlingAccelerationCurveCoefficient2
,
101 prefs::kFlingAccelerationCurveCoefficient3
,
102 prefs::kFlingMaxCancelToDownTimeInMs
,
103 prefs::kFlingMaxTapGapTimeInMs
,
104 prefs::kTabScrubActivationDelayInMS
,
105 prefs::kFlingVelocityCap
,
106 prefs::kLongPressTimeInSeconds
,
107 prefs::kMaxDistanceForTwoFingerTapInPixels
,
108 prefs::kMaxSecondsBetweenDoubleClick
,
109 prefs::kMaxSeparationForGestureTouchesInPixels
,
110 prefs::kMaxSwipeDeviationRatio
,
111 prefs::kMaxTouchDownDurationInSecondsForClick
,
112 prefs::kMaxTouchMoveInPixelsForClick
,
113 prefs::kMinDistanceForPinchScrollInPixels
,
114 prefs::kMinFlickSpeedSquared
,
115 prefs::kMinPinchUpdateDistanceInPixels
,
116 prefs::kMinRailBreakVelocity
,
117 prefs::kMinScrollDeltaSquared
,
118 prefs::kMinScrollSuccessiveVelocityEvents
,
119 prefs::kMinSwipeSpeed
,
120 prefs::kMinTouchDownDurationInSecondsForClick
,
121 prefs::kPointsBufferedForVelocity
,
122 prefs::kRailBreakProportion
,
123 prefs::kRailStartProportion
,
124 prefs::kSemiLongPressTimeInSeconds
,
127 const char* kFlingTouchpadPrefs
[] = {
128 prefs::kFlingCurveTouchpadAlpha
,
129 prefs::kFlingCurveTouchpadBeta
,
130 prefs::kFlingCurveTouchpadGamma
133 const char* kFlingTouchscreenPrefs
[] = {
134 prefs::kFlingCurveTouchscreenAlpha
,
135 prefs::kFlingCurveTouchscreenBeta
,
136 prefs::kFlingCurveTouchscreenGamma
,
139 GesturePrefsObserver::GesturePrefsObserver(PrefService
* prefs
)
141 // Clear for migration.
142 prefs
->ClearPref(kTouchScreenFlingAccelerationAdjustment
);
144 // Clear temporary pref gesture.config_is_trustworthy, so that in M33, we can
145 // remove it completely: crbug.com/269292.
146 prefs
->ClearPref(prefs::kGestureConfigIsTrustworthy
);
148 registrar_
.Init(prefs
);
149 registrar_
.RemoveAll();
150 base::Closure callback
= base::Bind(&GesturePrefsObserver::Update
,
151 base::Unretained(this));
153 base::Closure notify_callback
= base::Bind(&GesturePrefsObserver::Notify
,
154 base::Unretained(this));
156 for (size_t i
= 0; i
< arraysize(kPrefsToObserve
); ++i
)
157 registrar_
.Add(kPrefsToObserve
[i
], callback
);
159 const std::vector
<OverscrollPref
>& overscroll_prefs
= GetOverscrollPrefs();
160 for (size_t i
= 0; i
< overscroll_prefs
.size(); ++i
)
161 registrar_
.Add(overscroll_prefs
[i
].pref_name
, callback
);
163 for (size_t i
= 0; i
< arraysize(kFlingTouchpadPrefs
); ++i
)
164 registrar_
.Add(kFlingTouchpadPrefs
[i
], notify_callback
);
165 for (size_t i
= 0; i
< arraysize(kFlingTouchscreenPrefs
); ++i
)
166 registrar_
.Add(kFlingTouchscreenPrefs
[i
], notify_callback
);
171 GesturePrefsObserver::~GesturePrefsObserver() {}
173 void GesturePrefsObserver::Shutdown() {
174 registrar_
.RemoveAll();
177 void GesturePrefsObserver::Update() {
178 GestureConfiguration::set_fling_acceleration_curve_coefficients(0,
179 prefs_
->GetDouble(prefs::kFlingAccelerationCurveCoefficient0
));
180 GestureConfiguration::set_fling_acceleration_curve_coefficients(1,
181 prefs_
->GetDouble(prefs::kFlingAccelerationCurveCoefficient1
));
182 GestureConfiguration::set_fling_acceleration_curve_coefficients(2,
183 prefs_
->GetDouble(prefs::kFlingAccelerationCurveCoefficient2
));
184 GestureConfiguration::set_fling_acceleration_curve_coefficients(3,
185 prefs_
->GetDouble(prefs::kFlingAccelerationCurveCoefficient3
));
186 GestureConfiguration::set_fling_max_cancel_to_down_time_in_ms(
187 prefs_
->GetInteger(prefs::kFlingMaxCancelToDownTimeInMs
));
188 GestureConfiguration::set_fling_max_tap_gap_time_in_ms(
189 prefs_
->GetInteger(prefs::kFlingMaxTapGapTimeInMs
));
190 GestureConfiguration::set_tab_scrub_activation_delay_in_ms(
191 prefs_
->GetInteger(prefs::kTabScrubActivationDelayInMS
));
192 GestureConfiguration::set_fling_velocity_cap(
193 prefs_
->GetDouble(prefs::kFlingVelocityCap
));
194 GestureConfiguration::set_long_press_time_in_seconds(
196 prefs::kLongPressTimeInSeconds
));
197 GestureConfiguration::set_semi_long_press_time_in_seconds(
199 prefs::kSemiLongPressTimeInSeconds
));
200 GestureConfiguration::set_max_distance_for_two_finger_tap_in_pixels(
202 prefs::kMaxDistanceForTwoFingerTapInPixels
));
203 GestureConfiguration::set_max_seconds_between_double_click(
205 prefs::kMaxSecondsBetweenDoubleClick
));
206 GestureConfiguration::set_max_separation_for_gesture_touches_in_pixels(
208 prefs::kMaxSeparationForGestureTouchesInPixels
));
209 GestureConfiguration::set_max_swipe_deviation_ratio(
211 prefs::kMaxSwipeDeviationRatio
));
212 GestureConfiguration::set_max_touch_down_duration_in_seconds_for_click(
214 prefs::kMaxTouchDownDurationInSecondsForClick
));
215 GestureConfiguration::set_max_touch_move_in_pixels_for_click(
217 prefs::kMaxTouchMoveInPixelsForClick
));
218 GestureConfiguration::set_max_distance_between_taps_for_double_tap(
220 prefs::kMaxDistanceBetweenTapsForDoubleTap
));
221 GestureConfiguration::set_min_distance_for_pinch_scroll_in_pixels(
223 prefs::kMinDistanceForPinchScrollInPixels
));
224 GestureConfiguration::set_min_flick_speed_squared(
226 prefs::kMinFlickSpeedSquared
));
227 GestureConfiguration::set_min_pinch_update_distance_in_pixels(
229 prefs::kMinPinchUpdateDistanceInPixels
));
230 GestureConfiguration::set_min_rail_break_velocity(
232 prefs::kMinRailBreakVelocity
));
233 GestureConfiguration::set_min_scroll_delta_squared(
235 prefs::kMinScrollDeltaSquared
));
236 GestureConfiguration::set_min_scroll_successive_velocity_events(
238 prefs::kMinScrollSuccessiveVelocityEvents
));
239 GestureConfiguration::set_min_swipe_speed(
241 prefs::kMinSwipeSpeed
));
242 GestureConfiguration::set_min_touch_down_duration_in_seconds_for_click(
244 prefs::kMinTouchDownDurationInSecondsForClick
));
245 GestureConfiguration::set_points_buffered_for_velocity(
247 prefs::kPointsBufferedForVelocity
));
248 GestureConfiguration::set_rail_break_proportion(
250 prefs::kRailBreakProportion
));
251 GestureConfiguration::set_rail_start_proportion(
253 prefs::kRailStartProportion
));
254 GestureConfiguration::set_scroll_prediction_seconds(
255 prefs_
->GetDouble(prefs::kScrollPredictionSeconds
));
256 GestureConfiguration::set_show_press_delay_in_ms(
257 prefs_
->GetInteger(prefs::kShowPressDelayInMS
));
259 UpdateOverscrollPrefs();
262 void GesturePrefsObserver::UpdateOverscrollPrefs() {
263 const std::vector
<OverscrollPref
>& overscroll_prefs
= GetOverscrollPrefs();
264 for (size_t i
= 0; i
< overscroll_prefs
.size(); ++i
) {
265 content::SetOverscrollConfig(overscroll_prefs
[i
].config
,
266 static_cast<float>(prefs_
->GetDouble(overscroll_prefs
[i
].pref_name
)));
270 void GesturePrefsObserver::Notify() {
271 // Must do a notify to distribute the changes to all renderers.
272 content::NotificationService
* service
=
273 content::NotificationService::current();
274 service
->Notify(chrome::NOTIFICATION_BROWSER_FLING_CURVE_PARAMETERS_CHANGED
,
275 content::Source
<GesturePrefsObserver
>(this),
276 content::NotificationService::NoDetails());
282 GesturePrefsObserverFactoryAura
*
283 GesturePrefsObserverFactoryAura::GetInstance() {
284 return Singleton
<GesturePrefsObserverFactoryAura
>::get();
287 GesturePrefsObserverFactoryAura::GesturePrefsObserverFactoryAura()
288 : BrowserContextKeyedServiceFactory(
289 "GesturePrefsObserverAura",
290 BrowserContextDependencyManager::GetInstance()) {}
292 GesturePrefsObserverFactoryAura::~GesturePrefsObserverFactoryAura() {}
294 BrowserContextKeyedService
*
295 GesturePrefsObserverFactoryAura::BuildServiceInstanceFor(
296 content::BrowserContext
* profile
) const {
297 return new GesturePrefsObserver(static_cast<Profile
*>(profile
)->GetPrefs());
300 void GesturePrefsObserverFactoryAura::RegisterOverscrollPrefs(
301 user_prefs::PrefRegistrySyncable
* registry
) {
302 const std::vector
<OverscrollPref
>& overscroll_prefs
= GetOverscrollPrefs();
304 for (size_t i
= 0; i
< overscroll_prefs
.size(); ++i
) {
305 registry
->RegisterDoublePref(
306 overscroll_prefs
[i
].pref_name
,
307 content::GetOverscrollConfig(overscroll_prefs
[i
].config
),
308 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
312 void GesturePrefsObserverFactoryAura::RegisterFlingCurveParameters(
313 user_prefs::PrefRegistrySyncable
* registry
) {
314 content::RendererPreferences def_prefs
;
316 for (size_t i
= 0; i
< arraysize(kFlingTouchpadPrefs
); i
++)
317 registry
->RegisterDoublePref(
318 kFlingTouchpadPrefs
[i
],
319 def_prefs
.touchpad_fling_profile
[i
],
320 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
322 for (size_t i
= 0; i
< arraysize(kFlingTouchscreenPrefs
); i
++)
323 registry
->RegisterDoublePref(
324 kFlingTouchscreenPrefs
[i
],
325 def_prefs
.touchscreen_fling_profile
[i
],
326 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
329 void GesturePrefsObserverFactoryAura::RegisterProfilePrefs(
330 user_prefs::PrefRegistrySyncable
* registry
) {
331 registry
->RegisterDoublePref(
332 prefs::kFlingAccelerationCurveCoefficient0
,
333 GestureConfiguration::fling_acceleration_curve_coefficients(0),
334 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
335 registry
->RegisterDoublePref(
336 prefs::kFlingAccelerationCurveCoefficient1
,
337 GestureConfiguration::fling_acceleration_curve_coefficients(1),
338 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
339 registry
->RegisterDoublePref(
340 prefs::kFlingAccelerationCurveCoefficient2
,
341 GestureConfiguration::fling_acceleration_curve_coefficients(2),
342 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
343 registry
->RegisterDoublePref(
344 prefs::kFlingAccelerationCurveCoefficient3
,
345 GestureConfiguration::fling_acceleration_curve_coefficients(3),
346 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
347 registry
->RegisterIntegerPref(
348 prefs::kFlingMaxCancelToDownTimeInMs
,
349 GestureConfiguration::fling_max_cancel_to_down_time_in_ms(),
350 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
351 registry
->RegisterIntegerPref(
352 prefs::kFlingMaxTapGapTimeInMs
,
353 GestureConfiguration::fling_max_tap_gap_time_in_ms(),
354 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
355 registry
->RegisterIntegerPref(
356 prefs::kTabScrubActivationDelayInMS
,
357 GestureConfiguration::tab_scrub_activation_delay_in_ms(),
358 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
359 registry
->RegisterDoublePref(
360 prefs::kFlingVelocityCap
,
361 GestureConfiguration::fling_velocity_cap(),
362 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
363 registry
->RegisterDoublePref(
364 prefs::kLongPressTimeInSeconds
,
365 GestureConfiguration::long_press_time_in_seconds(),
366 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
367 registry
->RegisterDoublePref(
368 prefs::kSemiLongPressTimeInSeconds
,
369 GestureConfiguration::semi_long_press_time_in_seconds(),
370 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
371 registry
->RegisterDoublePref(
372 prefs::kMaxDistanceForTwoFingerTapInPixels
,
373 GestureConfiguration::max_distance_for_two_finger_tap_in_pixels(),
374 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
375 registry
->RegisterDoublePref(
376 prefs::kMaxSecondsBetweenDoubleClick
,
377 GestureConfiguration::max_seconds_between_double_click(),
378 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
379 registry
->RegisterDoublePref(
380 prefs::kMaxSeparationForGestureTouchesInPixels
,
381 GestureConfiguration::max_separation_for_gesture_touches_in_pixels(),
382 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
383 registry
->RegisterDoublePref(
384 prefs::kMaxSwipeDeviationRatio
,
385 GestureConfiguration::max_swipe_deviation_ratio(),
386 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
387 registry
->RegisterDoublePref(
388 prefs::kMaxTouchDownDurationInSecondsForClick
,
389 GestureConfiguration::max_touch_down_duration_in_seconds_for_click(),
390 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
391 registry
->RegisterDoublePref(
392 prefs::kMaxTouchMoveInPixelsForClick
,
393 GestureConfiguration::max_touch_move_in_pixels_for_click(),
394 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
395 registry
->RegisterDoublePref(
396 prefs::kMaxDistanceBetweenTapsForDoubleTap
,
397 GestureConfiguration::max_distance_between_taps_for_double_tap(),
398 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
399 registry
->RegisterDoublePref(
400 prefs::kMinDistanceForPinchScrollInPixels
,
401 GestureConfiguration::min_distance_for_pinch_scroll_in_pixels(),
402 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
403 registry
->RegisterDoublePref(
404 prefs::kMinFlickSpeedSquared
,
405 GestureConfiguration::min_flick_speed_squared(),
406 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
407 registry
->RegisterDoublePref(
408 prefs::kMinPinchUpdateDistanceInPixels
,
409 GestureConfiguration::min_pinch_update_distance_in_pixels(),
410 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
411 registry
->RegisterDoublePref(
412 prefs::kMinRailBreakVelocity
,
413 GestureConfiguration::min_rail_break_velocity(),
414 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
415 registry
->RegisterDoublePref(
416 prefs::kMinScrollDeltaSquared
,
417 GestureConfiguration::min_scroll_delta_squared(),
418 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
419 registry
->RegisterIntegerPref(
420 prefs::kMinScrollSuccessiveVelocityEvents
,
421 GestureConfiguration::min_scroll_successive_velocity_events(),
422 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
423 registry
->RegisterDoublePref(
424 prefs::kMinSwipeSpeed
,
425 GestureConfiguration::min_swipe_speed(),
426 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
427 registry
->RegisterDoublePref(
428 prefs::kMinTouchDownDurationInSecondsForClick
,
429 GestureConfiguration::min_touch_down_duration_in_seconds_for_click(),
430 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
431 registry
->RegisterIntegerPref(
432 prefs::kPointsBufferedForVelocity
,
433 GestureConfiguration::points_buffered_for_velocity(),
434 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
435 registry
->RegisterDoublePref(
436 prefs::kRailBreakProportion
,
437 GestureConfiguration::rail_break_proportion(),
438 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
439 registry
->RegisterDoublePref(
440 prefs::kRailStartProportion
,
441 GestureConfiguration::rail_start_proportion(),
442 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
443 registry
->RegisterDoublePref(
444 prefs::kScrollPredictionSeconds
,
445 GestureConfiguration::scroll_prediction_seconds(),
446 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
447 registry
->RegisterIntegerPref(
448 prefs::kShowPressDelayInMS
,
449 GestureConfiguration::show_press_delay_in_ms(),
450 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
452 // Register for migration.
453 registry
->RegisterDoublePref(
454 kTouchScreenFlingAccelerationAdjustment
,
456 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
458 RegisterOverscrollPrefs(registry
);
459 RegisterFlingCurveParameters(registry
);
461 // Register pref for a one-time wipe of all gesture preferences.
462 registry
->RegisterBooleanPref(
463 prefs::kGestureConfigIsTrustworthy
,
465 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
469 GesturePrefsObserverFactoryAura::ServiceIsCreatedWithBrowserContext() const {
470 // Create the observer as soon as the profile is created.
474 content::BrowserContext
*
475 GesturePrefsObserverFactoryAura::GetBrowserContextToUse(
476 content::BrowserContext
* context
) const {
477 // Use same gesture preferences on incognito windows.
478 return chrome::GetBrowserContextRedirectedInIncognito(context
);
481 bool GesturePrefsObserverFactoryAura::ServiceIsNULLWhileTesting() const {
482 // Some tests replace the PrefService of the TestingProfile after the
483 // GesturePrefsObserver has been created, which makes Shutdown()
484 // remove the registrar from a non-existent PrefService.