- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / webui / chromeos / salsa_ui.cc
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.
4
5 #include "chrome/browser/ui/webui/chromeos/salsa_ui.h"
6
7 #include "base/bind.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"
19
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.
24
25 namespace {
26
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,
67 };
68
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]))
74       continue;
75
76     if (!it->second) {
77       prefs->ClearPref(kWhitelist[it->first]);
78     } else {
79       prefs->Set(kWhitelist[it->first], *it->second);
80       delete it->second;
81     }
82   }
83 }
84
85 } // namespace
86
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);
92
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)));
102
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);
107
108   Profile* profile = Profile::FromWebUI(web_ui);
109   content::WebUIDataSource::Add(profile, html_source);
110 }
111
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_);
116
117   Profile* profile = Profile::FromWebUI(web_ui());
118   PrefService* prefs = profile->GetPrefs();
119
120   content::BrowserThread::PostTask(
121       content::BrowserThread::UI,
122       FROM_HERE,
123       base::Bind(&RevertPreferences, prefs, base::Owned(values_to_revert))
124     );
125 }
126
127 int SalsaUI::WhitelistIndex(const char* key) const {
128   if (!key)
129     return -1;
130
131   int len = arraysize(kWhitelist);
132   for (int i = 0; i < len; ++i) {
133     if (!strcmp(key, kWhitelist[i]))
134       return i;
135   }
136   return -1;
137 }
138
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))
143     return;
144
145   int index = WhitelistIndex(pref_name.c_str());
146   if (index < 0)
147     return;
148
149   Profile* profile = Profile::FromWebUI(web_ui());
150   PrefService* prefs = profile->GetPrefs();
151   const PrefService::Preference* pref =
152       prefs->FindPreference(kWhitelist[index]);
153
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) {
158     int int_val;
159     if (!value->GetAsInteger(&int_val))
160       return;
161     base::FundamentalValue double_val(static_cast<double>(int_val));
162     prefs->Set(kWhitelist[index], double_val);
163   }
164 }
165
166 void SalsaUI::BackupPreferenceValue(const base::ListValue* args) {
167   std::string pref_name;
168   if (!args->GetString(0, &pref_name))
169     return;
170
171   int index = WhitelistIndex(pref_name.c_str());
172   if (index < 0)
173     return;
174
175   Profile* profile = Profile::FromWebUI(web_ui());
176   PrefService* prefs = profile->GetPrefs();
177   const PrefService::Preference* pref =
178       prefs->FindPreference(kWhitelist[index]);
179
180   if (!pref)
181     return;
182
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();
188 }