gesture_prefs_observer_factory_aura.cc revision f2477e01787aa58f445919b809d89e252beef54f
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.
4
5#include "chrome/browser/ui/gesture_prefs_observer_factory_aura.h"
6
7#include <vector>
8
9#include "base/bind.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"
25
26using ui::GestureConfiguration;
27
28namespace {
29
30// TODO(rjkroege): Remove this deprecated pref in M29. http://crbug.com/160243.
31const char kTouchScreenFlingAccelerationAdjustment[] =
32    "gesture.touchscreen_fling_acceleration_adjustment";
33
34struct OverscrollPref {
35  const char* pref_name;
36  content::OverscrollConfig config;
37};
38
39const 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 },
58    };
59    overscroll_prefs.assign(kOverscrollPrefs,
60                            kOverscrollPrefs + arraysize(kOverscrollPrefs));
61  }
62  return overscroll_prefs;
63}
64
65// This class manages gesture configuration preferences.
66class GesturePrefsObserver : public BrowserContextKeyedService {
67 public:
68  explicit GesturePrefsObserver(PrefService* prefs);
69  virtual ~GesturePrefsObserver();
70
71  // BrowserContextKeyedService implementation.
72  virtual void Shutdown() OVERRIDE;
73
74 private:
75  // Notification callback invoked when browser-side preferences
76  // are updated and need to be pushed into ui::GesturePreferences.
77  void Update();
78
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.
82  void Notify();
83
84  // Notification helper to push overscroll preferences into
85  // content.
86  void UpdateOverscrollPrefs();
87
88  PrefChangeRegistrar registrar_;
89  PrefService* prefs_;
90
91  DISALLOW_COPY_AND_ASSIGN(GesturePrefsObserver);
92};
93
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
97const 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,
125};
126
127const char* kFlingTouchpadPrefs[] = {
128  prefs::kFlingCurveTouchpadAlpha,
129  prefs::kFlingCurveTouchpadBeta,
130  prefs::kFlingCurveTouchpadGamma
131};
132
133const char* kFlingTouchscreenPrefs[] = {
134  prefs::kFlingCurveTouchscreenAlpha,
135  prefs::kFlingCurveTouchscreenBeta,
136  prefs::kFlingCurveTouchscreenGamma,
137};
138
139GesturePrefsObserver::GesturePrefsObserver(PrefService* prefs)
140    : prefs_(prefs) {
141  // Clear for migration.
142  prefs->ClearPref(kTouchScreenFlingAccelerationAdjustment);
143
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);
147
148  registrar_.Init(prefs);
149  registrar_.RemoveAll();
150  base::Closure callback = base::Bind(&GesturePrefsObserver::Update,
151                                      base::Unretained(this));
152
153  base::Closure notify_callback = base::Bind(&GesturePrefsObserver::Notify,
154                                             base::Unretained(this));
155
156  for (size_t i = 0; i < arraysize(kPrefsToObserve); ++i)
157    registrar_.Add(kPrefsToObserve[i], callback);
158
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);
162
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);
167
168  Update();
169}
170
171GesturePrefsObserver::~GesturePrefsObserver() {}
172
173void GesturePrefsObserver::Shutdown() {
174  registrar_.RemoveAll();
175}
176
177void 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(
195      prefs_->GetDouble(
196          prefs::kLongPressTimeInSeconds));
197  GestureConfiguration::set_semi_long_press_time_in_seconds(
198      prefs_->GetDouble(
199          prefs::kSemiLongPressTimeInSeconds));
200  GestureConfiguration::set_max_distance_for_two_finger_tap_in_pixels(
201      prefs_->GetDouble(
202          prefs::kMaxDistanceForTwoFingerTapInPixels));
203  GestureConfiguration::set_max_seconds_between_double_click(
204      prefs_->GetDouble(
205          prefs::kMaxSecondsBetweenDoubleClick));
206  GestureConfiguration::set_max_separation_for_gesture_touches_in_pixels(
207      prefs_->GetDouble(
208          prefs::kMaxSeparationForGestureTouchesInPixels));
209  GestureConfiguration::set_max_swipe_deviation_ratio(
210      prefs_->GetDouble(
211          prefs::kMaxSwipeDeviationRatio));
212  GestureConfiguration::set_max_touch_down_duration_in_seconds_for_click(
213      prefs_->GetDouble(
214          prefs::kMaxTouchDownDurationInSecondsForClick));
215  GestureConfiguration::set_max_touch_move_in_pixels_for_click(
216      prefs_->GetDouble(
217          prefs::kMaxTouchMoveInPixelsForClick));
218  GestureConfiguration::set_max_distance_between_taps_for_double_tap(
219      prefs_->GetDouble(
220          prefs::kMaxDistanceBetweenTapsForDoubleTap));
221  GestureConfiguration::set_min_distance_for_pinch_scroll_in_pixels(
222      prefs_->GetDouble(
223          prefs::kMinDistanceForPinchScrollInPixels));
224  GestureConfiguration::set_min_flick_speed_squared(
225      prefs_->GetDouble(
226          prefs::kMinFlickSpeedSquared));
227  GestureConfiguration::set_min_pinch_update_distance_in_pixels(
228      prefs_->GetDouble(
229          prefs::kMinPinchUpdateDistanceInPixels));
230  GestureConfiguration::set_min_rail_break_velocity(
231      prefs_->GetDouble(
232          prefs::kMinRailBreakVelocity));
233  GestureConfiguration::set_min_scroll_delta_squared(
234      prefs_->GetDouble(
235          prefs::kMinScrollDeltaSquared));
236  GestureConfiguration::set_min_scroll_successive_velocity_events(
237      prefs_->GetInteger(
238          prefs::kMinScrollSuccessiveVelocityEvents));
239  GestureConfiguration::set_min_swipe_speed(
240      prefs_->GetDouble(
241          prefs::kMinSwipeSpeed));
242  GestureConfiguration::set_min_touch_down_duration_in_seconds_for_click(
243      prefs_->GetDouble(
244          prefs::kMinTouchDownDurationInSecondsForClick));
245  GestureConfiguration::set_points_buffered_for_velocity(
246      prefs_->GetInteger(
247          prefs::kPointsBufferedForVelocity));
248  GestureConfiguration::set_rail_break_proportion(
249      prefs_->GetDouble(
250          prefs::kRailBreakProportion));
251  GestureConfiguration::set_rail_start_proportion(
252      prefs_->GetDouble(
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));
258
259  UpdateOverscrollPrefs();
260}
261
262void 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)));
267  }
268}
269
270void 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());
277}
278
279}  // namespace
280
281// static
282GesturePrefsObserverFactoryAura*
283GesturePrefsObserverFactoryAura::GetInstance() {
284  return Singleton<GesturePrefsObserverFactoryAura>::get();
285}
286
287GesturePrefsObserverFactoryAura::GesturePrefsObserverFactoryAura()
288    : BrowserContextKeyedServiceFactory(
289        "GesturePrefsObserverAura",
290        BrowserContextDependencyManager::GetInstance()) {}
291
292GesturePrefsObserverFactoryAura::~GesturePrefsObserverFactoryAura() {}
293
294BrowserContextKeyedService*
295GesturePrefsObserverFactoryAura::BuildServiceInstanceFor(
296    content::BrowserContext* profile) const {
297  return new GesturePrefsObserver(static_cast<Profile*>(profile)->GetPrefs());
298}
299
300void GesturePrefsObserverFactoryAura::RegisterOverscrollPrefs(
301    user_prefs::PrefRegistrySyncable* registry) {
302  const std::vector<OverscrollPref>& overscroll_prefs = GetOverscrollPrefs();
303
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);
309  }
310}
311
312void GesturePrefsObserverFactoryAura::RegisterFlingCurveParameters(
313    user_prefs::PrefRegistrySyncable* registry) {
314  content::RendererPreferences def_prefs;
315
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);
321
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);
327}
328
329void 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);
451
452  // Register for migration.
453  registry->RegisterDoublePref(
454      kTouchScreenFlingAccelerationAdjustment,
455      0.0,
456      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
457
458  RegisterOverscrollPrefs(registry);
459  RegisterFlingCurveParameters(registry);
460
461  // Register pref for a one-time wipe of all gesture preferences.
462  registry->RegisterBooleanPref(
463      prefs::kGestureConfigIsTrustworthy,
464      false,
465      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
466}
467
468bool
469GesturePrefsObserverFactoryAura::ServiceIsCreatedWithBrowserContext() const {
470  // Create the observer as soon as the profile is created.
471  return true;
472}
473
474content::BrowserContext*
475GesturePrefsObserverFactoryAura::GetBrowserContextToUse(
476    content::BrowserContext* context) const {
477  // Use same gesture preferences on incognito windows.
478  return chrome::GetBrowserContextRedirectedInIncognito(context);
479}
480
481bool 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.
485  return true;
486}
487