Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / gesture_prefs_observer_factory_aura.cc
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/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"
26
27 using ui::GestureConfiguration;
28
29 namespace {
30
31 struct OverscrollPref {
32   const char* pref_name;
33   content::OverscrollConfig config;
34 };
35
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 },
55     };
56     overscroll_prefs.assign(kOverscrollPrefs,
57                             kOverscrollPrefs + arraysize(kOverscrollPrefs));
58   }
59   return overscroll_prefs;
60 }
61
62 // This class manages gesture configuration preferences.
63 class GesturePrefsObserver : public KeyedService {
64  public:
65   explicit GesturePrefsObserver(PrefService* prefs);
66   ~GesturePrefsObserver() override;
67
68   // KeyedService implementation.
69   void Shutdown() override;
70
71  private:
72   // Notification callback invoked when browser-side preferences
73   // are updated and need to be pushed into ui::GesturePreferences.
74   void Update();
75
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();
80
81   // Notification helper to push overscroll preferences into
82   // content.
83   void UpdateOverscrollPrefs();
84
85   PrefChangeRegistrar registrar_;
86   PrefService* prefs_;
87
88   DISALLOW_COPY_AND_ASSIGN(GesturePrefsObserver);
89 };
90
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,
100 };
101
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",
114 };
115
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]);
121   }
122
123   registrar_.Init(prefs);
124   registrar_.RemoveAll();
125   base::Closure callback = base::Bind(&GesturePrefsObserver::Update,
126                                       base::Unretained(this));
127
128   base::Closure notify_callback = base::Bind(&GesturePrefsObserver::Notify,
129                                              base::Unretained(this));
130
131   for (size_t i = 0; i < arraysize(kPrefsToObserve); ++i)
132     registrar_.Add(kPrefsToObserve[i], callback);
133
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);
137
138   Update();
139 }
140
141 GesturePrefsObserver::~GesturePrefsObserver() {}
142
143 void GesturePrefsObserver::Shutdown() {
144   registrar_.RemoveAll();
145 }
146
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)));
160
161   UpdateOverscrollPrefs();
162 }
163
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)));
169   }
170 }
171
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());
179 }
180
181 }  // namespace
182
183 // static
184 GesturePrefsObserverFactoryAura*
185 GesturePrefsObserverFactoryAura::GetInstance() {
186   return Singleton<GesturePrefsObserverFactoryAura>::get();
187 }
188
189 GesturePrefsObserverFactoryAura::GesturePrefsObserverFactoryAura()
190     : BrowserContextKeyedServiceFactory(
191         "GesturePrefsObserverAura",
192         BrowserContextDependencyManager::GetInstance()) {}
193
194 GesturePrefsObserverFactoryAura::~GesturePrefsObserverFactoryAura() {}
195
196 KeyedService* GesturePrefsObserverFactoryAura::BuildServiceInstanceFor(
197     content::BrowserContext* profile) const {
198   return new GesturePrefsObserver(static_cast<Profile*>(profile)->GetPrefs());
199 }
200
201 void GesturePrefsObserverFactoryAura::RegisterOverscrollPrefs(
202     user_prefs::PrefRegistrySyncable* registry) {
203   const std::vector<OverscrollPref>& overscroll_prefs = GetOverscrollPrefs();
204
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),
209         user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
210   }
211 }
212
213 void GesturePrefsObserverFactoryAura::RegisterProfilePrefs(
214     user_prefs::PrefRegistrySyncable* registry) {
215   GestureConfiguration* gesture_config = GestureConfiguration::GetInstance();
216   registry->RegisterIntegerPref(
217       prefs::kFlingMaxCancelToDownTimeInMs,
218       gesture_config->fling_max_cancel_to_down_time_in_ms(),
219       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
220   registry->RegisterIntegerPref(
221       prefs::kFlingMaxTapGapTimeInMs,
222       gesture_config->fling_max_tap_gap_time_in_ms(),
223       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
224   registry->RegisterIntegerPref(
225       prefs::kTabScrubActivationDelayInMs,
226       gesture_config->tab_scrub_activation_delay_in_ms(),
227       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
228   registry->RegisterIntegerPref(
229       prefs::kSemiLongPressTimeInMs,
230       gesture_config->semi_long_press_time_in_ms(),
231       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
232   registry->RegisterDoublePref(
233       prefs::kMaxSeparationForGestureTouchesInPixels,
234       gesture_config->max_separation_for_gesture_touches_in_pixels(),
235       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
236   RegisterOverscrollPrefs(registry);
237 }
238
239 bool
240 GesturePrefsObserverFactoryAura::ServiceIsCreatedWithBrowserContext() const {
241   // Create the observer as soon as the profile is created.
242   return true;
243 }
244
245 content::BrowserContext*
246 GesturePrefsObserverFactoryAura::GetBrowserContextToUse(
247     content::BrowserContext* context) const {
248   // Use same gesture preferences on incognito windows.
249   return chrome::GetBrowserContextRedirectedInIncognito(context);
250 }
251
252 bool GesturePrefsObserverFactoryAura::ServiceIsNULLWhileTesting() const {
253   // Some tests replace the PrefService of the TestingProfile after the
254   // GesturePrefsObserver has been created, which makes Shutdown()
255   // remove the registrar from a non-existent PrefService.
256   return true;
257 }