1 // Copyright 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/webui/chromeos/salsa_ui.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/prefs/pref_service.h"
10 #include "base/values.h"
11 #include "chrome/browser/browser_process.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/common/pref_names.h"
14 #include "chrome/common/url_constants.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "content/public/browser/web_ui.h"
17 #include "content/public/browser/web_ui_data_source.h"
18 #include "grit/browser_resources.h"
20 // Whitelist of which preferences are possible targets for Salsa treatments.
21 // If new preferences are added and they are to be used in an experiment, then
22 // they must be added to this list as well to keep chrome://salsa from
23 // changing arbitrary values.
27 const char* kWhitelist
[] = {
28 prefs::kFlingMaxCancelToDownTimeInMs
,
29 prefs::kFlingMaxTapGapTimeInMs
,
30 prefs::kLongPressTimeInSeconds
,
31 prefs::kLongPressTimeInSeconds
,
32 prefs::kMaxSecondsBetweenDoubleClick
,
33 prefs::kMaxSeparationForGestureTouchesInPixels
,
34 prefs::kMaxSwipeDeviationRatio
,
35 prefs::kMaxTouchDownDurationInSecondsForClick
,
36 prefs::kMaxTouchMoveInPixelsForClick
,
37 prefs::kMaxDistanceBetweenTapsForDoubleTap
,
38 prefs::kMaxDistanceForTwoFingerTapInPixels
,
39 prefs::kMinDistanceForPinchScrollInPixels
,
40 prefs::kMinFlickSpeedSquared
,
41 prefs::kMinPinchUpdateDistanceInPixels
,
42 prefs::kMinRailBreakVelocity
,
43 prefs::kMinScrollDeltaSquared
,
44 prefs::kMinSwipeSpeed
,
45 prefs::kMinTouchDownDurationInSecondsForClick
,
46 prefs::kPointsBufferedForVelocity
,
47 prefs::kRailBreakProportion
,
48 prefs::kRailStartProportion
,
49 prefs::kFlingAccelerationCurveCoefficient0
,
50 prefs::kFlingAccelerationCurveCoefficient1
,
51 prefs::kFlingAccelerationCurveCoefficient2
,
52 prefs::kFlingAccelerationCurveCoefficient3
,
53 prefs::kFlingVelocityCap
,
54 prefs::kTabScrubActivationDelayInMS
,
55 prefs::kOverscrollHorizontalThresholdComplete
,
56 prefs::kOverscrollVerticalThresholdComplete
,
57 prefs::kOverscrollMinimumThresholdStart
,
58 prefs::kOverscrollVerticalThresholdStart
,
59 prefs::kOverscrollHorizontalResistThreshold
,
60 prefs::kOverscrollVerticalResistThreshold
,
61 prefs::kFlingCurveTouchscreenAlpha
,
62 prefs::kFlingCurveTouchscreenBeta
,
63 prefs::kFlingCurveTouchscreenGamma
,
64 prefs::kFlingCurveTouchpadAlpha
,
65 prefs::kFlingCurveTouchpadBeta
,
66 prefs::kFlingCurveTouchpadGamma
,
69 void RevertPreferences(PrefService
* prefs
,
70 std::map
<int, const base::Value
*>* vals
) {
71 std::map
<int, const base::Value
*>::const_iterator it
;
72 for (it
= vals
->begin(); it
!= vals
->end(); ++it
) {
73 if (!prefs
->FindPreference(kWhitelist
[it
->first
]))
77 prefs
->ClearPref(kWhitelist
[it
->first
]);
79 prefs
->Set(kWhitelist
[it
->first
], *it
->second
);
87 SalsaUI::SalsaUI(content::WebUI
* web_ui
)
88 : content::WebUIController(web_ui
) {
89 // Set up the chrome://salsa source.
90 content::WebUIDataSource
* html_source
=
91 content::WebUIDataSource::Create(chrome::kChromeUISalsaHost
);
93 // Register callback handlers.
94 web_ui
->RegisterMessageCallback(
95 "salsaSetPreferenceValue",
96 base::Bind(&SalsaUI::SetPreferenceValue
,
97 base::Unretained(this)));
98 web_ui
->RegisterMessageCallback(
99 "salsaBackupPreferenceValue",
100 base::Bind(&SalsaUI::BackupPreferenceValue
,
101 base::Unretained(this)));
103 // Add required resources.
104 html_source
->AddResourcePath("salsa.css", IDR_SALSA_CSS
);
105 html_source
->AddResourcePath("salsa.js", IDR_SALSA_JS
);
106 html_source
->SetDefaultResource(IDR_SALSA_HTML
);
108 Profile
* profile
= Profile::FromWebUI(web_ui
);
109 content::WebUIDataSource::Add(profile
, html_source
);
112 SalsaUI::~SalsaUI() {
113 std::map
<int, const base::Value
*>* values_to_revert
=
114 new std::map
<int, const base::Value
*>;
115 values_to_revert
->swap(orig_values_
);
117 Profile
* profile
= Profile::FromWebUI(web_ui());
118 PrefService
* prefs
= profile
->GetPrefs();
120 content::BrowserThread::PostTask(
121 content::BrowserThread::UI
,
123 base::Bind(&RevertPreferences
, prefs
, base::Owned(values_to_revert
))
127 int SalsaUI::WhitelistIndex(const char* key
) const {
131 int len
= arraysize(kWhitelist
);
132 for (int i
= 0; i
< len
; ++i
) {
133 if (!strcmp(key
, kWhitelist
[i
]))
139 void SalsaUI::SetPreferenceValue(const base::ListValue
* args
) {
140 std::string pref_name
;
141 const base::Value
* value
;
142 if (!args
->GetString(0, &pref_name
) || !args
->Get(1, &value
))
145 int index
= WhitelistIndex(pref_name
.c_str());
149 Profile
* profile
= Profile::FromWebUI(web_ui());
150 PrefService
* prefs
= profile
->GetPrefs();
151 const PrefService::Preference
* pref
=
152 prefs
->FindPreference(kWhitelist
[index
]);
154 if (pref
->GetType() == value
->GetType()) {
155 prefs
->Set(kWhitelist
[index
], *value
);
156 } else if (pref
->GetType() == base::Value::TYPE_DOUBLE
&&
157 value
->GetType() == base::Value::TYPE_INTEGER
) {
159 if (!value
->GetAsInteger(&int_val
))
161 base::FundamentalValue
double_val(static_cast<double>(int_val
));
162 prefs
->Set(kWhitelist
[index
], double_val
);
166 void SalsaUI::BackupPreferenceValue(const base::ListValue
* args
) {
167 std::string pref_name
;
168 if (!args
->GetString(0, &pref_name
))
171 int index
= WhitelistIndex(pref_name
.c_str());
175 Profile
* profile
= Profile::FromWebUI(web_ui());
176 PrefService
* prefs
= profile
->GetPrefs();
177 const PrefService::Preference
* pref
=
178 prefs
->FindPreference(kWhitelist
[index
]);
183 // Get our own copy of the user defined value or NULL if they are using the
184 // default. You have to make a copy since they'll be used in the destructor
185 // to restore the values and we need to make sure they're still around.
186 orig_values_
[index
] =
187 pref
->IsDefaultValue() ? NULL
: pref
->GetValue()->DeepCopy();