Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / ui / gesture_prefs_observer_factory_aura.cc
blobb9717262f596af05299af05d26084cdeae281972
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"
7 #include <vector>
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/keyed_service/content/browser_context_dependency_manager.h"
19 #include "components/keyed_service/core/keyed_service.h"
20 #include "components/pref_registry/pref_registry_syncable.h"
21 #include "content/public/browser/notification_observer.h"
22 #include "content/public/browser/notification_service.h"
23 #include "content/public/browser/overscroll_configuration.h"
24 #include "content/public/common/renderer_preferences.h"
25 #include "ui/events/gesture_detection/gesture_configuration.h"
27 using ui::GestureConfiguration;
29 namespace {
31 struct OverscrollPref {
32 const char* pref_name;
33 content::OverscrollConfig config;
36 const std::vector<OverscrollPref>& GetOverscrollPrefs() {
37 CR_DEFINE_STATIC_LOCAL(std::vector<OverscrollPref>, overscroll_prefs, ());
38 if (overscroll_prefs.empty()) {
39 using namespace content;
40 const OverscrollPref kOverscrollPrefs[] = {
41 { prefs::kOverscrollHorizontalThresholdComplete,
42 OVERSCROLL_CONFIG_HORIZ_THRESHOLD_COMPLETE },
43 { prefs::kOverscrollVerticalThresholdComplete,
44 OVERSCROLL_CONFIG_VERT_THRESHOLD_COMPLETE },
45 { prefs::kOverscrollMinimumThresholdStart,
46 OVERSCROLL_CONFIG_HORIZ_THRESHOLD_START_TOUCHSCREEN },
47 { prefs::kOverscrollMinimumThresholdStartTouchpad,
48 OVERSCROLL_CONFIG_HORIZ_THRESHOLD_START_TOUCHPAD },
49 { prefs::kOverscrollVerticalThresholdStart,
50 OVERSCROLL_CONFIG_VERT_THRESHOLD_START },
51 { prefs::kOverscrollHorizontalResistThreshold,
52 OVERSCROLL_CONFIG_HORIZ_RESIST_AFTER },
53 { prefs::kOverscrollVerticalResistThreshold,
54 OVERSCROLL_CONFIG_VERT_RESIST_AFTER },
56 overscroll_prefs.assign(kOverscrollPrefs,
57 kOverscrollPrefs + arraysize(kOverscrollPrefs));
59 return overscroll_prefs;
62 // This class manages gesture configuration preferences.
63 class GesturePrefsObserver : public KeyedService {
64 public:
65 explicit GesturePrefsObserver(PrefService* prefs);
66 ~GesturePrefsObserver() override;
68 // KeyedService implementation.
69 void Shutdown() override;
71 private:
72 // Notification callback invoked when browser-side preferences
73 // are updated and need to be pushed into ui::GesturePreferences.
74 void Update();
76 // Notification callback invoked when the fling deacceleration
77 // gesture preferences are changed from chrome://gesture.
78 // Broadcasts the changes all renderers where they are used.
79 void Notify();
81 // Notification helper to push overscroll preferences into
82 // content.
83 void UpdateOverscrollPrefs();
85 PrefChangeRegistrar registrar_;
86 PrefService* prefs_;
88 DISALLOW_COPY_AND_ASSIGN(GesturePrefsObserver);
91 // The list of prefs we want to observe.
92 // Note that this collection of settings should correspond to the settings used
93 // in ui/events/gestures/gesture_configuration.h
94 const char* kPrefsToObserve[] = {
95 prefs::kFlingMaxCancelToDownTimeInMs,
96 prefs::kFlingMaxTapGapTimeInMs,
97 prefs::kTabScrubActivationDelayInMs,
98 prefs::kMaxSeparationForGestureTouchesInPixels,
99 prefs::kSemiLongPressTimeInMs,
102 const char* kPrefsToRemove[] = {
103 "gesture.fling_acceleration_curve_coefficient_0",
104 "gesture.fling_acceleration_curve_coefficient_1",
105 "gesture.fling_acceleration_curve_coefficient_2",
106 "gesture.fling_acceleration_curve_coefficient_3",
107 "gesture.semi_long_press_time_in_seconds",
108 "flingcurve.touchpad_alpha",
109 "flingcurve.touchpad_beta",
110 "flingcurve.touchpad_gamma",
111 "flingcurve.touchscreen_alpha",
112 "flingcurve.touchscreen_beta",
113 "flingcurve.touchscreen_gamma",
116 GesturePrefsObserver::GesturePrefsObserver(PrefService* prefs)
117 : prefs_(prefs) {
118 for (size_t i = 0; i < arraysize(kPrefsToRemove); ++i) {
119 if (prefs->FindPreference(kPrefsToRemove[i]))
120 prefs->ClearPref(kPrefsToRemove[i]);
123 registrar_.Init(prefs);
124 registrar_.RemoveAll();
125 base::Closure callback = base::Bind(&GesturePrefsObserver::Update,
126 base::Unretained(this));
128 base::Closure notify_callback = base::Bind(&GesturePrefsObserver::Notify,
129 base::Unretained(this));
131 for (size_t i = 0; i < arraysize(kPrefsToObserve); ++i)
132 registrar_.Add(kPrefsToObserve[i], callback);
134 const std::vector<OverscrollPref>& overscroll_prefs = GetOverscrollPrefs();
135 for (size_t i = 0; i < overscroll_prefs.size(); ++i)
136 registrar_.Add(overscroll_prefs[i].pref_name, callback);
138 Update();
141 GesturePrefsObserver::~GesturePrefsObserver() {}
143 void GesturePrefsObserver::Shutdown() {
144 registrar_.RemoveAll();
147 void GesturePrefsObserver::Update() {
148 GestureConfiguration* gesture_config = GestureConfiguration::GetInstance();
149 gesture_config->set_fling_max_cancel_to_down_time_in_ms(
150 prefs_->GetInteger(prefs::kFlingMaxCancelToDownTimeInMs));
151 gesture_config->set_fling_max_tap_gap_time_in_ms(
152 prefs_->GetInteger(prefs::kFlingMaxTapGapTimeInMs));
153 gesture_config->set_tab_scrub_activation_delay_in_ms(
154 prefs_->GetInteger(prefs::kTabScrubActivationDelayInMs));
155 gesture_config->set_semi_long_press_time_in_ms(
156 prefs_->GetInteger(prefs::kSemiLongPressTimeInMs));
157 gesture_config->set_max_separation_for_gesture_touches_in_pixels(
158 static_cast<float>(
159 prefs_->GetDouble(prefs::kMaxSeparationForGestureTouchesInPixels)));
161 UpdateOverscrollPrefs();
164 void GesturePrefsObserver::UpdateOverscrollPrefs() {
165 const std::vector<OverscrollPref>& overscroll_prefs = GetOverscrollPrefs();
166 for (size_t i = 0; i < overscroll_prefs.size(); ++i) {
167 content::SetOverscrollConfig(overscroll_prefs[i].config,
168 static_cast<float>(prefs_->GetDouble(overscroll_prefs[i].pref_name)));
172 void GesturePrefsObserver::Notify() {
173 // Must do a notify to distribute the changes to all renderers.
174 content::NotificationService* service =
175 content::NotificationService::current();
176 service->Notify(chrome::NOTIFICATION_BROWSER_FLING_CURVE_PARAMETERS_CHANGED,
177 content::Source<GesturePrefsObserver>(this),
178 content::NotificationService::NoDetails());
181 } // namespace
183 // static
184 GesturePrefsObserverFactoryAura*
185 GesturePrefsObserverFactoryAura::GetInstance() {
186 return base::Singleton<GesturePrefsObserverFactoryAura>::get();
189 GesturePrefsObserverFactoryAura::GesturePrefsObserverFactoryAura()
190 : BrowserContextKeyedServiceFactory(
191 "GesturePrefsObserverAura",
192 BrowserContextDependencyManager::GetInstance()) {}
194 GesturePrefsObserverFactoryAura::~GesturePrefsObserverFactoryAura() {}
196 KeyedService* GesturePrefsObserverFactoryAura::BuildServiceInstanceFor(
197 content::BrowserContext* profile) const {
198 return new GesturePrefsObserver(static_cast<Profile*>(profile)->GetPrefs());
201 void GesturePrefsObserverFactoryAura::RegisterOverscrollPrefs(
202 user_prefs::PrefRegistrySyncable* registry) {
203 const std::vector<OverscrollPref>& overscroll_prefs = GetOverscrollPrefs();
205 for (size_t i = 0; i < overscroll_prefs.size(); ++i) {
206 registry->RegisterDoublePref(
207 overscroll_prefs[i].pref_name,
208 content::GetOverscrollConfig(overscroll_prefs[i].config));
212 void GesturePrefsObserverFactoryAura::RegisterProfilePrefs(
213 user_prefs::PrefRegistrySyncable* registry) {
214 GestureConfiguration* gesture_config = GestureConfiguration::GetInstance();
215 registry->RegisterIntegerPref(
216 prefs::kFlingMaxCancelToDownTimeInMs,
217 gesture_config->fling_max_cancel_to_down_time_in_ms());
218 registry->RegisterIntegerPref(prefs::kFlingMaxTapGapTimeInMs,
219 gesture_config->fling_max_tap_gap_time_in_ms());
220 registry->RegisterIntegerPref(
221 prefs::kTabScrubActivationDelayInMs,
222 gesture_config->tab_scrub_activation_delay_in_ms());
223 registry->RegisterIntegerPref(prefs::kSemiLongPressTimeInMs,
224 gesture_config->semi_long_press_time_in_ms());
225 registry->RegisterDoublePref(
226 prefs::kMaxSeparationForGestureTouchesInPixels,
227 gesture_config->max_separation_for_gesture_touches_in_pixels());
228 RegisterOverscrollPrefs(registry);
231 bool
232 GesturePrefsObserverFactoryAura::ServiceIsCreatedWithBrowserContext() const {
233 // Create the observer as soon as the profile is created.
234 return true;
237 content::BrowserContext*
238 GesturePrefsObserverFactoryAura::GetBrowserContextToUse(
239 content::BrowserContext* context) const {
240 // Use same gesture preferences on incognito windows.
241 return chrome::GetBrowserContextRedirectedInIncognito(context);
244 bool GesturePrefsObserverFactoryAura::ServiceIsNULLWhileTesting() const {
245 // Some tests replace the PrefService of the TestingProfile after the
246 // GesturePrefsObserver has been created, which makes Shutdown()
247 // remove the registrar from a non-existent PrefService.
248 return true;