• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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::kMaxSeparationForGestureTouchesInPixels,
29   prefs::kFlingAccelerationCurveCoefficient0,
30   prefs::kFlingAccelerationCurveCoefficient1,
31   prefs::kFlingAccelerationCurveCoefficient2,
32   prefs::kFlingAccelerationCurveCoefficient3,
33   prefs::kTabScrubActivationDelayInMS,
34   prefs::kOverscrollHorizontalThresholdComplete,
35   prefs::kOverscrollVerticalThresholdComplete,
36   prefs::kOverscrollMinimumThresholdStart,
37   prefs::kOverscrollVerticalThresholdStart,
38   prefs::kOverscrollHorizontalResistThreshold,
39   prefs::kOverscrollVerticalResistThreshold,
40   prefs::kFlingCurveTouchscreenAlpha,
41   prefs::kFlingCurveTouchscreenBeta,
42   prefs::kFlingCurveTouchscreenGamma,
43   prefs::kFlingCurveTouchpadAlpha,
44   prefs::kFlingCurveTouchpadBeta,
45   prefs::kFlingCurveTouchpadGamma,
46 };
47 
RevertPreferences(PrefService * prefs,std::map<int,const base::Value * > * vals)48 void RevertPreferences(PrefService* prefs,
49                        std::map<int, const base::Value*>* vals) {
50   std::map<int, const base::Value*>::const_iterator it;
51   for (it = vals->begin(); it != vals->end(); ++it) {
52     if (!prefs->FindPreference(kWhitelist[it->first]))
53       continue;
54 
55     if (!it->second) {
56       prefs->ClearPref(kWhitelist[it->first]);
57     } else {
58       prefs->Set(kWhitelist[it->first], *it->second);
59       delete it->second;
60     }
61   }
62 }
63 
64 } // namespace
65 
SalsaUI(content::WebUI * web_ui)66 SalsaUI::SalsaUI(content::WebUI* web_ui)
67     : content::WebUIController(web_ui) {
68   // Set up the chrome://salsa source.
69   content::WebUIDataSource* html_source =
70       content::WebUIDataSource::Create(chrome::kChromeUISalsaHost);
71 
72   // Register callback handlers.
73   web_ui->RegisterMessageCallback(
74       "salsaSetPreferenceValue",
75       base::Bind(&SalsaUI::SetPreferenceValue,
76                  base::Unretained(this)));
77   web_ui->RegisterMessageCallback(
78       "salsaBackupPreferenceValue",
79       base::Bind(&SalsaUI::BackupPreferenceValue,
80                  base::Unretained(this)));
81 
82   // Add required resources.
83   html_source->AddResourcePath("salsa.css", IDR_SALSA_CSS);
84   html_source->AddResourcePath("salsa.js", IDR_SALSA_JS);
85   html_source->SetDefaultResource(IDR_SALSA_HTML);
86 
87   Profile* profile = Profile::FromWebUI(web_ui);
88   content::WebUIDataSource::Add(profile, html_source);
89 }
90 
~SalsaUI()91 SalsaUI::~SalsaUI() {
92   std::map<int, const base::Value*>* values_to_revert =
93       new std::map<int, const base::Value*>;
94   values_to_revert->swap(orig_values_);
95 
96   Profile* profile = Profile::FromWebUI(web_ui());
97   PrefService* prefs = profile->GetPrefs();
98 
99   content::BrowserThread::PostTask(
100       content::BrowserThread::UI,
101       FROM_HERE,
102       base::Bind(&RevertPreferences, prefs, base::Owned(values_to_revert))
103     );
104 }
105 
WhitelistIndex(const char * key) const106 int SalsaUI::WhitelistIndex(const char* key) const {
107   if (!key)
108     return -1;
109 
110   int len = arraysize(kWhitelist);
111   for (int i = 0; i < len; ++i) {
112     if (!strcmp(key, kWhitelist[i]))
113       return i;
114   }
115   return -1;
116 }
117 
SetPreferenceValue(const base::ListValue * args)118 void SalsaUI::SetPreferenceValue(const base::ListValue* args) {
119   std::string pref_name;
120   const base::Value* value;
121   if (!args->GetString(0, &pref_name) || !args->Get(1, &value))
122     return;
123 
124   int index = WhitelistIndex(pref_name.c_str());
125   if (index < 0)
126     return;
127 
128   Profile* profile = Profile::FromWebUI(web_ui());
129   PrefService* prefs = profile->GetPrefs();
130   const PrefService::Preference* pref =
131       prefs->FindPreference(kWhitelist[index]);
132 
133   if (pref->GetType() == value->GetType()) {
134     prefs->Set(kWhitelist[index], *value);
135   } else if (pref->GetType() == base::Value::TYPE_DOUBLE &&
136              value->GetType() == base::Value::TYPE_INTEGER) {
137     int int_val;
138     if (!value->GetAsInteger(&int_val))
139       return;
140     base::FundamentalValue double_val(static_cast<double>(int_val));
141     prefs->Set(kWhitelist[index], double_val);
142   }
143 }
144 
BackupPreferenceValue(const base::ListValue * args)145 void SalsaUI::BackupPreferenceValue(const base::ListValue* args) {
146   std::string pref_name;
147   if (!args->GetString(0, &pref_name))
148     return;
149 
150   int index = WhitelistIndex(pref_name.c_str());
151   if (index < 0)
152     return;
153 
154   Profile* profile = Profile::FromWebUI(web_ui());
155   PrefService* prefs = profile->GetPrefs();
156   const PrefService::Preference* pref =
157       prefs->FindPreference(kWhitelist[index]);
158 
159   if (!pref)
160     return;
161 
162   // Get our own copy of the user defined value or NULL if they are using the
163   // default. You have to make a copy since they'll be used in the destructor
164   // to restore the values and we need to make sure they're still around.
165   orig_values_[index] =
166       pref->IsDefaultValue() ? NULL : pref->GetValue()->DeepCopy();
167 }
168